summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2009-11-18 18:40:14 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2009-11-18 18:40:14 +0100
commit48ac0ffecdf244d04ed6cb4f4c560aeea5ba7f23 (patch)
tree05b6563cbb3321d725f7c671ce3e27d81807f93e
parentc82f2781d2ed372e918ea5b5529ead57ff95fc2a (diff)
downloadrsyslog-48ac0ffecdf244d04ed6cb4f4c560aeea5ba7f23.tar.gz
rsyslog-48ac0ffecdf244d04ed6cb4f4c560aeea5ba7f23.tar.xz
rsyslog-48ac0ffecdf244d04ed6cb4f4c560aeea5ba7f23.zip
milestone commit: first driver layer call done
... does not really run. We can now call into the epoll driver, but not handle epoll(). The driver also needs more modifications.
-rw-r--r--doc/src/tls.diabin5173 -> 5201 bytes
-rw-r--r--runtime/netstrms.c3
-rw-r--r--runtime/nsd.h4
-rw-r--r--runtime/nsd_ptcp.c2
-rw-r--r--runtime/nsdpoll_ptcp.c127
-rw-r--r--runtime/nsdpoll_ptcp.h14
-rw-r--r--runtime/nspoll.c18
-rw-r--r--runtime/nspoll.h14
-rw-r--r--runtime/nssel.c1
-rw-r--r--runtime/rsyslog.h4
-rw-r--r--tcpsrv.c118
11 files changed, 285 insertions, 20 deletions
diff --git a/doc/src/tls.dia b/doc/src/tls.dia
index 91b0d706..d7c9811d 100644
--- a/doc/src/tls.dia
+++ b/doc/src/tls.dia
Binary files differ
diff --git a/runtime/netstrms.c b/runtime/netstrms.c
index 6b28e7ea..e9ff2568 100644
--- a/runtime/netstrms.c
+++ b/runtime/netstrms.c
@@ -36,6 +36,7 @@
#include "nsd.h"
#include "netstrm.h"
#include "nssel.h"
+#include "nspoll.h"
#include "netstrms.h"
MODULE_TYPE_LIB
@@ -304,6 +305,7 @@ ENDObjClassInit(netstrms)
BEGINmodExit
CODESTARTmodExit
nsselClassExit();
+ nspollClassExit();
netstrmsClassExit();
netstrmClassExit(); /* we use this object, so we must exit it after we are finished */
ENDmodExit
@@ -322,6 +324,7 @@ CODESTARTmodInit
/* Initialize all classes that are in our module - this includes ourselfs */
CHKiRet(netstrmClassInit(pModInfo));
CHKiRet(nsselClassInit(pModInfo));
+ CHKiRet(nspollClassInit(pModInfo));
CHKiRet(netstrmsClassInit(pModInfo));
ENDmodInit
/* vi:set ai:
diff --git a/runtime/nsd.h b/runtime/nsd.h
index bcd5a926..fc34ad6e 100644
--- a/runtime/nsd.h
+++ b/runtime/nsd.h
@@ -91,8 +91,8 @@ ENDinterface(nsdsel)
BEGINinterface(nsdpoll) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Construct)(nsdpoll_t **ppThis);
rsRetVal (*Destruct)(nsdpoll_t **ppThis);
- rsRetVal (*Ctl)(nsdpoll_t *pThis, int fd, int op, epoll_event_t *event);
- rsRetVal (*Wait)(nsdpoll_t *pThis, epoll_event_t *events, int maxevents, int timeout);
+ rsRetVal (*Ctl)(nsdpoll_t *pNsdpoll, nsd_t *pNsd, int id, void *pUsr, int op);
+ rsRetVal (*Wait)(nsdpoll_t *pNsdpoll, int timeout, int *idRdy, void **ppUsr);
ENDinterface(nsdpoll)
#define nsdpollCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
diff --git a/runtime/nsd_ptcp.c b/runtime/nsd_ptcp.c
index fe31ab40..6feee71d 100644
--- a/runtime/nsd_ptcp.c
+++ b/runtime/nsd_ptcp.c
@@ -821,6 +821,7 @@ ENDObjClassInit(nsd_ptcp)
BEGINmodExit
CODESTARTmodExit
+ nsdpoll_ptcpClassExit();
nsdsel_ptcpClassExit();
nsd_ptcpClassExit();
ENDmodExit
@@ -839,6 +840,7 @@ CODESTARTmodInit
/* Initialize all classes that are in our module - this includes ourselfs */
CHKiRet(nsd_ptcpClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
CHKiRet(nsdsel_ptcpClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
+ CHKiRet(nsdpoll_ptcpClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
ENDmodInit
/* vi:set ai:
*/
diff --git a/runtime/nsdpoll_ptcp.c b/runtime/nsdpoll_ptcp.c
index b6b7af77..ed683acc 100644
--- a/runtime/nsdpoll_ptcp.c
+++ b/runtime/nsdpoll_ptcp.c
@@ -28,11 +28,16 @@
#include <assert.h>
#include <errno.h>
#include <string.h>
+#if HAVE_SYS_EPOLL_H
+# include <sys/epoll.h>
+#endif
#include "rsyslog.h"
#include "module-template.h"
#include "obj.h"
#include "errmsg.h"
+#include "srUtils.h"
+#include "nspoll.h"
#include "nsd_ptcp.h"
#include "nsdpoll_ptcp.h"
#include "unlimited_select.h"
@@ -43,9 +48,66 @@ DEFobjCurrIf(errmsg)
DEFobjCurrIf(glbl)
+/* -START------------------------- helpers for event list ------------------------------------ */
+
+/* add new entry to list. We assume that the fd is not already present and DO NOT check this!
+ * Returns newly created entry in pEvtLst.
+ * rgerhards, 2009-11-18
+ */
+static inline rsRetVal
+addEvent(nsdpoll_ptcp_t *pThis, int id, void *pUsr, int mode, nsd_ptcp_t *pSock, nsdpoll_epollevt_lst_t **pEvtLst) {
+ nsdpoll_epollevt_lst_t *pNew;
+ DEFiRet;
+
+ CHKmalloc(pNew = (nsdpoll_epollevt_lst_t*) malloc(sizeof(nsdpoll_epollevt_lst_t)));
+ pNew->id = id;
+ pNew->pUsr = pUsr;
+ pNew->pSock = pSock;
+ pNew->event.events = EPOLLET; /* always use edge-triggered mode */
+ if(mode & NSDPOLL_IN)
+ pNew->event.events |= EPOLLIN;
+ if(mode & NSDPOLL_OUT)
+ pNew->event.events |= EPOLLOUT;
+ pNew->event.data.u64 = (uint64) pNew;
+ pNew->pNext = pThis->pRoot;
+ pThis->pRoot = pNew;
+ *pEvtLst = pNew;
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* remove the entry identified by id/pUsr from the list.
+ * rgerhards, 2009-11-18
+ */
+static inline rsRetVal
+delEvent(nsdpoll_ptcp_t *pThis, int id, void *pUsr) {
+ DEFiRet;
+ // TODO: XXX add code!
+#warning delEvent implementation is missing!
+ RETiRet;
+}
+
+
+/* -END--------------------------- helpers for event list ------------------------------------ */
+
+
/* Standard-Constructor
*/
BEGINobjConstruct(nsdpoll_ptcp) /* be sure to specify the object type also in END macro! */
+# if defined(EPOLL_CLOEXEC) && defined(HAVE_EPOLL_CREATE1)
+ DBGPRINTF("imudp uses epoll_create1()\n");
+ pThis->efd = epoll_create1(EPOLL_CLOEXEC);
+# else
+ DBGPRINTF("imudp uses epoll_create()\n");
+ pThis->efd = epoll_create(NUM_EPOLL_EVENTS);
+# endif
+ if(pThis->efd < 0) {
+ DBGPRINTF("epoll_create1() could not create fd\n");
+ ABORT_FINALIZE(RS_RET_IO_ERROR);
+ }
+finalize_it:
ENDobjConstruct(nsdpoll_ptcp)
@@ -55,19 +117,76 @@ CODESTARTobjDestruct(nsdpoll_ptcp)
ENDobjDestruct(nsdpoll_ptcp)
-/* Add a socket to the select set */
+/* Modify socket set */
static rsRetVal
-Ctl(nsdpoll_t *pThis, int fd, int op, epoll_event_t *event) {
+Ctl(nsdpoll_t *pNsdpoll, nsd_t *pNsd, int id, void *pUsr, int mode) {
+ nsdpoll_ptcp_t *pThis = (nsdpoll_ptcp_t*) pNsdpoll;
+ nsd_ptcp_t *pSock = (nsd_ptcp_t*) pNsd;
+ nsdpoll_epollevt_lst_t *pEventLst;
+ int errSave;
+ char errStr[512];
DEFiRet;
+
+ if(mode == NSDPOLL_ADD) {
+ dbgprintf("adding nsdpoll entry %d/%p\n", id, pUsr);
+ CHKiRet(addEvent(pThis, id, pUsr, mode, pSock, &pEventLst));
+ if(epoll_ctl(pThis->efd, EPOLL_CTL_ADD, pSock->sock, &pEventLst->event) < 0) {
+ errSave = errno;
+ rs_strerror_r(errSave, errStr, sizeof(errStr));
+ errmsg.LogError(errSave, RS_RET_ERR_EPOLL_CTL,
+ "epoll_ctl failed on fd %d, id %d/%p, op %d with %s\n",
+ pSock->sock, id, pUsr, mode, errStr);
+ }
+ } else if(mode == NSDPOLL_DEL) {
+ // TODO: XXX : code missing!
+ dbgprintf("removing nsdpoll entry %d/%p\n", id, pUsr);
+ } else {
+ dbgprintf("program error: invalid NSDPOLL_mode %d - ignoring request\n", mode);
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+
+finalize_it:
RETiRet;
}
-/* Wait for io to become ready.
+/* Wait for io to become ready. After the successful call, idRdy contains the
+ * id set by the caller for that i/o event, ppUsr is a pointer to a location
+ * where the user pointer shall be stored.
+ * TODO: this is a trivial implementation that only polls one event at a time. We
+ * may later extend it to poll for multiple events, what would cause less
+ * overhead.
+ * rgerhards, 2009-11-18
*/
static rsRetVal
-Wait(nsdpoll_t *pThis, epoll_event_t *events, int maxevents, int timeout) {
+Wait(nsdpoll_t *pNsdpoll, int timeout, int *idRdy, void **ppUsr) {
+ nsdpoll_ptcp_t *pThis = (nsdpoll_ptcp_t*) pNsdpoll;
+ nsdpoll_epollevt_lst_t *pOurEvt;
+ struct epoll_event event;
+ int nfds;
DEFiRet;
+
+ assert(idRdy != NULL);
+ assert(ppUsr != NULL);
+
+ nfds = epoll_wait(pThis->efd, &event, 1, timeout);
+ if(nfds == -1) {
+ if(errno == EINTR) {
+ ABORT_FINALIZE(RS_RET_EINTR);
+ } else {
+ DBGPRINTF("epoll() returned with error code %d\n", errno);
+ ABORT_FINALIZE(RS_RET_ERR_EPOLL);
+ }
+ } else if(nfds == 0) {
+ ABORT_FINALIZE(RS_RET_TIMEOUT);
+ }
+
+ /* we got a valid event, so tell the caller... */
+ pOurEvt = (nsdpoll_epollevt_lst_t*) event.data.u64;
+ *idRdy = pOurEvt->id;
+ *ppUsr = pOurEvt->pUsr;
+
+finalize_it:
RETiRet;
}
diff --git a/runtime/nsdpoll_ptcp.h b/runtime/nsdpoll_ptcp.h
index 36d39da7..ccdb87f0 100644
--- a/runtime/nsdpoll_ptcp.h
+++ b/runtime/nsdpoll_ptcp.h
@@ -26,10 +26,24 @@
#include "nsd.h"
typedef nsdpoll_if_t nsdpoll_ptcp_if_t; /* we just *implement* this interface */
+/* a helper object to keep track of the epoll event records
+ * Note that we need to keep track of that list because we need to
+ * free the events when they are no longer needed.
+ */
+typedef struct nsdpoll_epollevt_lst_s nsdpoll_epollevt_lst_t;
+struct nsdpoll_epollevt_lst_s {
+ epoll_event_t event;
+ int id;
+ void *pUsr;
+ nsd_ptcp_t *pSock; /* our associated netstream driver data */
+ nsdpoll_epollevt_lst_t *pNext;
+};
/* the nsdpoll_ptcp object */
struct nsdpoll_ptcp_s {
BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
+ int efd; /* file descriptor used by epoll */
+ nsdpoll_epollevt_lst_t *pRoot; /* Root of the epoll event list */
};
/* interface is defined in nsd.h, we just implement it! */
diff --git a/runtime/nspoll.c b/runtime/nspoll.c
index ff0b1e92..4413c2c7 100644
--- a/runtime/nspoll.c
+++ b/runtime/nspoll.c
@@ -68,7 +68,7 @@ loadDrvr(nspoll_t *pThis)
pBaseDrvrName = pThis->pBaseDrvrName;
if(pBaseDrvrName == NULL) /* if no drvr name is set, use system default */
pBaseDrvrName = glbl.GetDfltNetstrmDrvr();
- if(snprintf((char*)szDrvrName, sizeof(szDrvrName), "lmnspoll_%s", pBaseDrvrName) == sizeof(szDrvrName))
+ if(snprintf((char*)szDrvrName, sizeof(szDrvrName), "lmnsdpoll_%s", pBaseDrvrName) == sizeof(szDrvrName))
ABORT_FINALIZE(RS_RET_DRVRNAME_TOO_LONG);
CHKmalloc(pThis->pDrvrName = (uchar*) strdup((char*)szDrvrName));
@@ -79,6 +79,7 @@ loadDrvr(nspoll_t *pThis)
* about this hack, but for the time being it is efficient and clean
* enough. -- rgerhards, 2008-04-18
*/
+RUNLOG_VAR("%s", szDrvrName+2);
CHKiRet(obj.UseObj(__FILE__, szDrvrName+2, DONT_LOAD_LIB, (void*) &pThis->Drvr));
finalize_it:
@@ -119,9 +120,11 @@ ConstructFinalize(nspoll_t *pThis)
{
DEFiRet;
ISOBJ_TYPE_assert(pThis, nspoll);
+RUNLOG_STR("trying to load epoll driver\n");
CHKiRet(loadDrvr(pThis));
CHKiRet(pThis->Drvr.Construct(&pThis->pDrvrData));
finalize_it:
+dbgprintf("XXX: done trying to load epoll driver, state %d\n", iRet);
RETiRet;
}
@@ -129,12 +132,11 @@ finalize_it:
/* Carries out the actual wait (all done in lower layers)
*/
static rsRetVal
-Wait(nspoll_t *pThis, epoll_event_t *events, int maxevents, int timeout) {
+Wait(nspoll_t *pThis, int timeout, int *idRdy, void **ppUsr) {
DEFiRet;
ISOBJ_TYPE_assert(pThis, nspoll);
- assert(events != NULL);
- assert(maxevents > 0);
- iRet = pThis->Drvr.Wait(pThis->pDrvrData, events, maxevents, timeout);
+ assert(idRdy != NULL);
+ iRet = pThis->Drvr.Wait(pThis->pDrvrData, timeout, idRdy, ppUsr);
RETiRet;
}
@@ -143,11 +145,10 @@ Wait(nspoll_t *pThis, epoll_event_t *events, int maxevents, int timeout) {
* rgerhards, 2009-11-18
*/
static rsRetVal
-Ctl(nspoll_t *pThis, int fd, int op, epoll_event_t *event) {
+Ctl(nspoll_t *pThis, nsd_t *pNsd, int id, void *pUsr, int op) {
DEFiRet;
ISOBJ_TYPE_assert(pThis, nspoll);
- assert(event != NULL);
- iRet = pThis->Drvr.Ctl(pThis->pDrvrData, fd, op, event);
+ iRet = pThis->Drvr.Ctl(pThis->pDrvrData, pNsd, id, pUsr, op);
RETiRet;
}
@@ -188,6 +189,7 @@ ENDObjClassExit(nspoll)
*/
BEGINObjClassInit(nspoll, 1, OBJ_IS_CORE_MODULE) /* class, version */
/* request objects we use */
+ DBGPRINTF("doing nspollClassInit\n");
CHKiRet(objUse(glbl, CORE_COMPONENT));
/* set our own handlers */
diff --git a/runtime/nspoll.h b/runtime/nspoll.h
index 19efd38b..9d39e017 100644
--- a/runtime/nspoll.h
+++ b/runtime/nspoll.h
@@ -26,6 +26,15 @@
#include "netstrms.h"
+/* some operations to be portable when we do not have epoll() available */
+#define NSDPOLL_ADD 1
+#define NSDPOLL_DEL 2
+
+/* and some mode specifiers for waiting on input/output */
+#define NSDPOLL_IN 1 /* EPOLLIN */
+#define NSDPOLL_OUT 2 /* EPOLLOUT */
+/* next is 4, 8, 16, ... - must be bit values, as they are ored! */
+
/* the nspoll object */
struct nspoll_s {
BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
@@ -41,8 +50,9 @@ BEGINinterface(nspoll) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Construct)(nspoll_t **ppThis);
rsRetVal (*ConstructFinalize)(nspoll_t *pThis);
rsRetVal (*Destruct)(nspoll_t **ppThis);
- rsRetVal (*Ctl)(nspoll_t *pThis, int fd, int op, epoll_event_t *event);
- rsRetVal (*Wait)(nspoll_t *pThis, epoll_event_t *events, int maxevents, int timeout);
+ rsRetVal (*Wait)(nspoll_t *pNsdpoll, int timeout, int *idRdy, void **ppUsr);
+ rsRetVal (*Ctl)(nspoll_t *pNsdpoll, nsd_t *pNsd, int id, void *pUsr, int op);
+ rsRetVal (*IsEPollSupported)(void); /* static method */
ENDinterface(nspoll)
#define nspollCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
diff --git a/runtime/nssel.c b/runtime/nssel.c
index d11d5fe1..7c5be3a9 100644
--- a/runtime/nssel.c
+++ b/runtime/nssel.c
@@ -219,6 +219,7 @@ ENDObjClassExit(nssel)
*/
BEGINObjClassInit(nssel, 1, OBJ_IS_CORE_MODULE) /* class, version */
/* request objects we use */
+ DBGPRINTF("doing nsselClassInit\n");
CHKiRet(objUse(glbl, CORE_COMPONENT));
/* set our own handlers */
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index c5f7a9ea..b8ebafd9 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -414,6 +414,10 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_NO_RULESET= -2158,/**< no ruleset name as specified where one was needed */
RS_RET_PARSER_NOT_FOUND = -2159,/**< parser with the specified name was not found */
RS_RET_COULD_NOT_PARSE = -2160,/**< (this) parser could not parse the message (no error, means try next one) */
+ RS_RET_EINTR = -2161, /**< EINTR occured during a system call (not necessarily an error) */
+ RS_RET_ERR_EPOLL = -2162, /**< epoll() returned with an unexpected error code */
+ RS_RET_ERR_EPOLL_CTL = -2163, /**< epol_ctll() returned with an unexpected error code */
+ RS_RET_TIMEOUT = -2164, /**< timeout occured during operation */
/* RainerScript error messages (range 1000.. 1999) */
RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */
diff --git a/tcpsrv.c b/tcpsrv.c
index ef453f3a..75055195 100644
--- a/tcpsrv.c
+++ b/tcpsrv.c
@@ -68,6 +68,7 @@
#include "netstrms.h"
#include "netstrm.h"
#include "nssel.h"
+#include "nspoll.h"
#include "errmsg.h"
#include "ruleset.h"
#include "unicode-helper.h"
@@ -89,6 +90,7 @@ DEFobjCurrIf(net)
DEFobjCurrIf(netstrms)
DEFobjCurrIf(netstrm)
DEFobjCurrIf(nssel)
+DEFobjCurrIf(nspoll)
DEFobjCurrIf(prop)
@@ -521,10 +523,13 @@ doReceive(tcpsrv_t *pThis, tcps_sess_t **ppSess)
}
-/* This function is called to gather input. */
+/* This function is called to gather input.
+ * This variant here is only used if we need to work with a netstream driver
+ * that does not support epoll().
+ */
#pragma GCC diagnostic ignored "-Wempty-body"
-static rsRetVal
-Run(tcpsrv_t *pThis)
+static inline rsRetVal
+RunSelect(tcpsrv_t *pThis)
{
DEFiRet;
int nfds;
@@ -532,7 +537,7 @@ Run(tcpsrv_t *pThis)
int iTCPSess;
int bIsReady;
tcps_sess_t *pNewSess;
- nssel_t *pSel;
+ nssel_t *pSel = NULL;
ISOBJ_TYPE_assert(pThis, tcpsrv);
@@ -606,6 +611,110 @@ finalize_it: /* this is a very special case - this time only we do not exit the
#pragma GCC diagnostic warning "-Wempty-body"
+/* This function is called to gather input. It tries doing that via the epoll()
+ * interface. If the driver does not support that, it falls back to calling its
+ * select() equivalent.
+ * rgerhards, 2009-11-18
+ */
+#pragma GCC diagnostic ignored "-Wempty-body"
+static rsRetVal
+Run(tcpsrv_t *pThis)
+{
+ DEFiRet;
+ int nfds;
+ int i;
+ int iTCPSess;
+ int bIsReady;
+ tcps_sess_t *pNewSess;
+ nspoll_t *pPoll;
+ rsRetVal localRet;
+
+ ISOBJ_TYPE_assert(pThis, tcpsrv);
+
+ /* this is an endless loop - it is terminated by the framework canelling
+ * this thread. Thus, we also need to instantiate a cancel cleanup handler
+ * to prevent us from leaking anything. -- rgerhards, 20080-04-24
+ */
+#warning implement cancel cleanup handler!
+ //pthread_cleanup_push(RunCancelCleanup, (void*) &pSel);
+ if((localRet = nspoll.Construct(&pPoll)) == RS_RET_OK) {
+ localRet = nspoll.ConstructFinalize(pPoll);
+ }
+ if(localRet != RS_RET_OK) {
+ /* fall back to select */
+ dbgprintf("tcpsrv could not use epoll() interface, iRet=%d, using select()\n", localRet);
+ iRet = RunSelect(pThis);
+ FINALIZE;
+ }
+
+ dbgprintf("we would use the poll handler, currently not implemented!\n");
+#if 0
+ while(1) {
+ CHKiRet(nssel.Construct(&pSel));
+ // TODO: set driver
+ CHKiRet(nssel.ConstructFinalize(pSel));
+
+ /* Add the TCP listen sockets to the list of read descriptors. */
+ for(i = 0 ; i < pThis->iLstnCurr ; ++i) {
+ CHKiRet(nssel.Add(pSel, pThis->ppLstn[i], NSDSEL_RD));
+ }
+
+ /* do the sessions */
+ iTCPSess = TCPSessGetNxtSess(pThis, -1);
+ while(iTCPSess != -1) {
+ /* TODO: access to pNsd is NOT really CLEAN, use method... */
+ CHKiRet(nssel.Add(pSel, pThis->pSessions[iTCPSess]->pStrm, NSDSEL_RD));
+ /* now get next... */
+ iTCPSess = TCPSessGetNxtSess(pThis, iTCPSess);
+ }
+
+ /* wait for io to become ready */
+ CHKiRet(nssel.Wait(pSel, &nfds));
+ if(glbl.GetGlobalInputTermState() == 1)
+ break; /* terminate input! */
+
+ for(i = 0 ; i < pThis->iLstnCurr ; ++i) {
+ if(glbl.GetGlobalInputTermState() == 1)
+ ABORT_FINALIZE(RS_RET_FORCE_TERM);
+ CHKiRet(nssel.IsReady(pSel, pThis->ppLstn[i], NSDSEL_RD, &bIsReady, &nfds));
+ if(bIsReady) {
+ DBGPRINTF("New connect on NSD %p.\n", pThis->ppLstn[i]);
+ SessAccept(pThis, pThis->ppLstnPort[i], &pNewSess, pThis->ppLstn[i]);
+ --nfds; /* indicate we have processed one */
+ }
+ }
+
+ /* now check the sessions */
+ iTCPSess = TCPSessGetNxtSess(pThis, -1);
+ while(nfds && iTCPSess != -1) {
+ if(glbl.GetGlobalInputTermState() == 1)
+ ABORT_FINALIZE(RS_RET_FORCE_TERM);
+ CHKiRet(nssel.IsReady(pSel, pThis->pSessions[iTCPSess]->pStrm, NSDSEL_RD, &bIsReady, &nfds));
+ if(bIsReady) {
+ doReceive(pThis, &pThis->pSessions[iTCPSess]);
+ --nfds; /* indicate we have processed one */
+ }
+ iTCPSess = TCPSessGetNxtSess(pThis, iTCPSess);
+ }
+ CHKiRet(nssel.Destruct(&pSel));
+finalize_it: /* this is a very special case - this time only we do not exit the function,
+ * because that would not help us either. So we simply retry it. Let's see
+ * if that actually is a better idea. Exiting the loop wasn't we always
+ * crashed, which made sense (the rest of the engine was not prepared for
+ * that) -- rgerhards, 2008-05-19
+ */
+ /*EMPTY*/;
+ }
+#endif
+ /* note that this point is usually not reached */
+// pthread_cleanup_pop(1); /* remove cleanup handler */
+
+finalize_it:
+ RETiRet;
+}
+#pragma GCC diagnostic warning "-Wempty-body"
+
+
/* Standard-Constructor */
BEGINobjConstruct(tcpsrv) /* be sure to specify the object type also in END macro! */
pThis->iSessMax = TCPSESS_MAX_DEFAULT;
@@ -969,6 +1078,7 @@ BEGINObjClassInit(tcpsrv, 1, OBJ_IS_LOADABLE_MODULE) /* class, version - CHANGE
CHKiRet(objUse(netstrms, LM_NETSTRMS_FILENAME));
CHKiRet(objUse(netstrm, DONT_LOAD_LIB));
CHKiRet(objUse(nssel, DONT_LOAD_LIB));
+ CHKiRet(objUse(nspoll, DONT_LOAD_LIB));
CHKiRet(objUse(tcps_sess, DONT_LOAD_LIB));
CHKiRet(objUse(conf, CORE_COMPONENT));
CHKiRet(objUse(glbl, CORE_COMPONENT));