diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2009-11-18 18:40:14 +0100 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2009-11-18 18:40:14 +0100 |
commit | 48ac0ffecdf244d04ed6cb4f4c560aeea5ba7f23 (patch) | |
tree | 05b6563cbb3321d725f7c671ce3e27d81807f93e | |
parent | c82f2781d2ed372e918ea5b5529ead57ff95fc2a (diff) | |
download | rsyslog-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.dia | bin | 5173 -> 5201 bytes | |||
-rw-r--r-- | runtime/netstrms.c | 3 | ||||
-rw-r--r-- | runtime/nsd.h | 4 | ||||
-rw-r--r-- | runtime/nsd_ptcp.c | 2 | ||||
-rw-r--r-- | runtime/nsdpoll_ptcp.c | 127 | ||||
-rw-r--r-- | runtime/nsdpoll_ptcp.h | 14 | ||||
-rw-r--r-- | runtime/nspoll.c | 18 | ||||
-rw-r--r-- | runtime/nspoll.h | 14 | ||||
-rw-r--r-- | runtime/nssel.c | 1 | ||||
-rw-r--r-- | runtime/rsyslog.h | 4 | ||||
-rw-r--r-- | tcpsrv.c | 118 |
11 files changed, 285 insertions, 20 deletions
diff --git a/doc/src/tls.dia b/doc/src/tls.dia Binary files differindex 91b0d706..d7c9811d 100644 --- a/doc/src/tls.dia +++ b/doc/src/tls.dia 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) */ @@ -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)); |