Skip to content

Commit 7e35caf

Browse files
authored
Merge pull request #94 from sy-c/fix-daemon-1
v2.7.3
2 parents c6a0c39 + 872c03b commit 7e35caf

File tree

2 files changed

+44
-16
lines changed

2 files changed

+44
-16
lines changed

doc/releaseNotes.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,6 @@ This file describes the main feature changes for each InfoLogger released versio
159159
- increased default value of rxMaxConnections from 1024 to 2048. This is the number of concurrent clients allowed to connect to o2-infologger-daemon. Can be changed in configuration file.
160160
- o2-infologger-server: improved logging per thread/database.
161161
- o2-infologger-newdb: added option to skip user creation
162+
163+
# v2.7.3 - 30/09/2024
164+
- o2-infologger-daemon: removed limitation of 1024 connections (was because of hard limit in select() system call, replaced now by poll()).

src/infoLoggerD.cxx

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <fcntl.h>
3333
#include <sys/socket.h>
3434
#include <sys/un.h>
35+
#include <sys/poll.h>
3536

3637
#include <sys/stat.h>
3738
#include <string.h>
@@ -197,6 +198,7 @@ int checkDirAndCreate(const char* dir, SimpleLog* log = NULL)
197198
typedef struct {
198199
int socket;
199200
std::string buffer; // currently pending data
201+
int pollIx; // index of client in poll structure
200202
} t_clientConnection;
201203

202204
class InfoLoggerD : public Daemon
@@ -214,6 +216,8 @@ class InfoLoggerD : public Daemon
214216

215217
unsigned long long numberOfMessagesReceived = 0;
216218
std::list<t_clientConnection> clients;
219+
struct pollfd *fds = nullptr; // array for poll()
220+
int nfds = 0; // size of array
217221

218222
TR_client_configuration cfgCx; // config for transport
219223
TR_client_handle hCx = nullptr; // handle to server transport
@@ -451,6 +455,9 @@ InfoLoggerD::~InfoLoggerD()
451455
for (auto c : clients) {
452456
close(c.socket);
453457
}
458+
if (fds) {
459+
free(fds);
460+
}
454461
if (hCx != nullptr) {
455462
TR_client_stop(hCx);
456463
}
@@ -462,28 +469,37 @@ Daemon::LoopStatus InfoLoggerD::doLoop()
462469
return LoopStatus::Error;
463470
}
464471

465-
fd_set readfds;
466-
FD_ZERO(&readfds);
467-
FD_SET(rxSocket, &readfds);
468-
int nfds = rxSocket;
469-
for (auto client : clients) {
470-
FD_SET(client.socket, &readfds);
471-
if (client.socket > nfds) {
472-
nfds = client.socket;
472+
bool updateFds = false; // raise this flag to renew structure (change in client list)
473+
if (fds == nullptr) {
474+
// create new poll structure based on current list of clients
475+
size_t sz = sizeof(struct pollfd) * (clients.size() + 1);
476+
fds = (struct pollfd *)malloc(sz);
477+
if (fds == nullptr) {
478+
return LoopStatus::Error;
479+
}
480+
memset(fds, 0, sz);
481+
nfds = 1;
482+
fds[0].fd = rxSocket;
483+
fds[0].events = POLLIN;
484+
485+
for (auto &client : clients) {
486+
if (client.socket<0) continue;
487+
fds[nfds].fd = client.socket;
488+
fds[nfds].events = POLLIN;
489+
fds[nfds].revents = 0;
490+
client.pollIx = nfds; // keep index of fds for this client, to be able to check poll result
491+
nfds++;
473492
}
474493
}
475-
nfds++;
476-
477-
struct timeval selectTimeout;
478-
selectTimeout.tv_sec = 1;
479-
selectTimeout.tv_usec = 0;
480494

481-
if (select(nfds, &readfds, NULL, NULL, &selectTimeout) > 0) {
495+
// poll with 1 second timeout
496+
if (poll(fds, nfds, 1000) > 0) {
482497

483498
// check existing clients
484499
int cleanupNeeded = 0;
485500
for (auto& client : clients) {
486-
if (FD_ISSET(client.socket, &readfds)) {
501+
if (client.socket<0) continue;
502+
if ((client.pollIx >= 0) && (fds[client.pollIx].revents)) {
487503
char newData[1024000]; // never read more than 10k at a time... allows to round-robin through clients
488504
int bytesRead = read(client.socket, newData, sizeof(newData));
489505
if (bytesRead > 0) {
@@ -544,10 +560,11 @@ Daemon::LoopStatus InfoLoggerD::doLoop()
544560
if (cleanupNeeded) {
545561
clients.remove_if([](t_clientConnection& c) { return (c.socket == -1); });
546562
log.info("%d clients disconnected, now having %d/%d", cleanupNeeded, (int)clients.size(), configInfoLoggerD.rxMaxConnections);
563+
updateFds = 1;
547564
}
548565

549566
// handle new connection requests
550-
if (FD_ISSET(rxSocket, &readfds)) {
567+
if (fds[0].revents) {
551568
struct sockaddr_un socketAddress;
552569
socklen_t socketAddressLen = sizeof(socketAddress);
553570
int tmpSocket = accept(rxSocket, (struct sockaddr*)&socketAddress, &socketAddressLen);
@@ -574,9 +591,17 @@ Daemon::LoopStatus InfoLoggerD::doLoop()
574591
newClient.buffer.clear();
575592
clients.push_back(newClient);
576593
log.info("New client: %d/%d", (int)clients.size(), configInfoLoggerD.rxMaxConnections);
594+
updateFds = 1;
577595
}
578596
}
579597
}
598+
599+
if (updateFds) {
600+
if (fds != nullptr) {
601+
free(fds);
602+
}
603+
fds = nullptr;
604+
}
580605
}
581606

582607
return LoopStatus::Ok;

0 commit comments

Comments
 (0)