bool nofork = false;
bool unlimitcore = false;
-time_t TIME = time(NULL);
+time_t TIME = time(NULL), OLDTIME = time(NULL);
#ifdef USE_KQUEUE
-int kq, lkq;
+int kq, lkq, skq;
#endif
namespace nspace
WritePID(PID);
/* setup select call */
+#ifndef USE_KQUEUE
FD_ZERO(&selectFds);
+#endif
log(DEBUG,"InspIRCd: startup: zero selects");
log(VERBOSE,"InspIRCd: startup: portCount = %lu", (unsigned long)portCount);
#ifdef USE_KQUEUE
kq = kqueue();
lkq = kqueue();
- if ((kq == -1) || (lkq == -1))
+ skq = kqueue();
+ if ((kq == -1) || (lkq == -1) || (skq == -1))
{
log(DEFAULT,"main: kqueue() failed!");
printf("ERROR: could not initialise kqueue event system. Shutting down.\n");
printf("ERROR: could not initialise listening sockets in kqueue. Shutting down.\n");
}
}
+ for (int t = 0; t != SERVERportCount; t++)
+ {
+ struct kevent ke;
+ if (me[t])
+ {
+ log(DEBUG,"kqueue: Add listening SERVER socket to events, kq=%d socket=%d",skq,me[t]->fd);
+ EV_SET(&ke, me[t]->fd, EVFILT_READ, EV_ADD, 0, 5, NULL);
+ int i = kevent(skq, &ke, 1, 0, 0, NULL);
+ if (i == -1)
+ {
+ log(DEFAULT,"main: add server listen ports to kqueue failed!");
+ printf("ERROR: could not initialise listening server sockets in kqueue. Shutting down.\n");
+ }
+ }
+ }
+
+
#else
log(DEFAULT,"Using standard select socket engine.");
#endif
#ifdef USE_KQUEUE
struct kevent ke;
+ struct kevent ke_list[33];
struct timespec ts;
#endif
fd_set serverfds;
tval.tv_usec = 10000L;
tval.tv_sec = 0;
int total_in_this_set = 0;
- int i = 0, v = 0;
+ int i = 0, v = 0, j = 0, cycle_iter = 0;
bool expire_run = false;
/* main loop, this never returns */
#ifdef _POSIX_PRIORITY_SCHEDULING
sched_yield();
#endif
- // poll dns queue
- dns_poll();
+#ifndef USE_KQUEUE
FD_ZERO(&sfd);
+#endif
// we only read time() once per iteration rather than tons of times!
+ OLDTIME = TIME;
TIME = time(NULL);
+ dns_poll();
+
// *FIX* Instead of closing sockets in kill_link when they receive the ERROR :blah line, we should queue
// them in a list, then reap the list every second or so.
if (((TIME % 5) == 0) && (!expire_run))
// fix by brain - this must be below any manipulation of the hashmap by modules
user_hash::iterator count2 = clientlist.begin();
+#ifdef USE_KQUEUE
+ ts.tv_sec = 0;
+ ts.tv_nsec = 30000L;
+ i = kevent(skq, NULL, 0, &ke, 1, &ts);
+ if (i > 0)
+ {
+ log(DEBUG,"kqueue: Listening server socket event, i=%d, ke.ident=%d",i,ke.ident);
+ for (int x = 0; x != SERVERportCount; x++)
+ {
+ if ((me[x]) && (ke.ident == me[x]->fd))
+ {
+
+#else
FD_ZERO(&serverfds);
-
for (int x = 0; x != SERVERportCount; x++)
{
if (me[x])
FD_SET(me[x]->fd, &serverfds);
}
-
- // serverFds timevals went here
-
tvs.tv_usec = 30000L;
tvs.tv_sec = 0;
int servresult = select(32767, &serverfds, NULL, NULL, &tvs);
{
if ((me[x]) && (FD_ISSET (me[x]->fd, &serverfds)))
{
+#endif
char remotehost[MAXBUF],resolved[MAXBUF];
length = sizeof (client);
incomingSockfd = accept (me[x]->fd, (sockaddr *) &client, &length);
while (count2 != clientlist.end())
{
+#ifndef USE_KQUEUE
FD_ZERO(&sfd);
+#endif
total_in_this_set = 0;
endingiter = count2;
count2 = xcount; // roll back to where we were
#else
- dns_poll();
// KQUEUE: We don't go through a loop to fill the fd_set so instead we must manually do this loop every now and again.
// TODO: We dont need to do all this EVERY loop iteration, tone down the visits to this if we're using kqueue.
- while (count2 != clientlist.end())
+ cycle_iter++;
+ if (cycle_iter > 10) while (count2 != clientlist.end())
{
+ cycle_iter = 0;
if (count2 != clientlist.end())
{
curr = count2->second;
#else
ts.tv_sec = 0;
ts.tv_nsec = 30000L;
- i = kevent(lkq, NULL, 0, &ke, 1, &ts);
- if (i > 0)
+ i = kevent(lkq, NULL, 0, ke_list, 32, &ts);
+ if (i > 0) for (j = 0; j < i; j++)
{
log(DEBUG,"kqueue: Listening socket event, i=%d, ke.ident=%d",i,ke.ident);
// this isnt as efficient as it could be, we could create a reference table
// compared to the number of clients (possibly over 2000)
for (count = 0; count < boundPortCount; count++)
{
- if (ke.ident == openSockfd[count])
+ if (ke_list[j].ident == openSockfd[count])
{
#endif
char target[MAXBUF], resolved[MAXBUF];
AddClient(incomingSockfd, resolved, ports[count], false, inet_ntoa (client.sin_addr));
log(DEBUG,"InspIRCd: adding client on port %lu fd=%lu",(unsigned long)ports[count],(unsigned long)incomingSockfd);
}
- goto label;
+ //goto label;
}
}
}