From 62c3b0a585a4abcaae7794e487627bea29712be8 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Tue, 27 Aug 2019 16:51:00 +0200 Subject: [PATCH 01/23] don't send errlog on all logClients --- modules/libcom/src/log/iocLog.c | 14 ++++++++++++++ modules/libcom/src/log/logClient.c | 4 ---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/modules/libcom/src/log/iocLog.c b/modules/libcom/src/log/iocLog.c index e62da2050..8cb1349a1 100644 --- a/modules/libcom/src/log/iocLog.c +++ b/modules/libcom/src/log/iocLog.c @@ -18,8 +18,10 @@ #define epicsExportSharedSymbols #include "envDefs.h" +#include "errlog.h" #include "logClient.h" #include "iocLog.h" +#include "epicsExit.h" int iocLogDisable = 0; @@ -74,6 +76,14 @@ void epicsShareAPI epicsShareAPI iocLogFlush (void) } } +/* + * logClientDestroy() + */ +static void iocLogClientDestroy (logClientId id) +{ + errlogRemoveListeners (logClientSendMessage, id); +} + /* * iocLogClientInit() */ @@ -89,6 +99,10 @@ static logClientId iocLogClientInit (void) return NULL; } id = logClientCreate (addr, port); + if (id != NULL) { + errlogAddListener (logClientSendMessage, id); + epicsAtExit (iocLogClientDestroy, id); + } return id; } diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 99ee671d9..b076d50cb 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -154,8 +154,6 @@ static void logClientDestroy (logClientId id) return; } - errlogRemoveListeners ( logClientSendMessage, (void *) pClient ); - logClientClose ( pClient ); epicsMutexDestroy ( pClient->mutex ); @@ -549,8 +547,6 @@ logClientId epicsShareAPI logClientCreate ( pClient->name, LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT ); } - errlogAddListener ( logClientSendMessage, (void *) pClient ); - return (void *) pClient; } From 243287877311748057baa61937ea8d8a530f8d27 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Tue, 27 Aug 2019 17:34:01 +0200 Subject: [PATCH 02/23] speed up logRestart thread termination at exit --- modules/libcom/src/log/logClient.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index b076d50cb..96382a2eb 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -44,6 +44,7 @@ typedef struct { SOCKET sock; epicsThreadId restartThreadId; epicsEventId stateChangeNotify; + epicsEventId shutdownNotify; unsigned connectCount; unsigned nextMsgIndex; unsigned connected; @@ -113,6 +114,7 @@ static void logClientDestroy (logClientId id) epicsMutexMustLock ( pClient->mutex ); pClient->shutdown = 1u; epicsMutexUnlock ( pClient->mutex ); + epicsEventSignal ( pClient->shutdownNotify ); /* unblock log client thread blocking in send() or connect() */ interruptInfo = @@ -157,8 +159,8 @@ static void logClientDestroy (logClientId id) logClientClose ( pClient ); epicsMutexDestroy ( pClient->mutex ); - epicsEventDestroy ( pClient->stateChangeNotify ); + epicsEventDestroy ( pClient->shutdownNotify ); free ( pClient ); } @@ -461,8 +463,8 @@ static void logClientRestart ( logClientId id ) else { logClientConnect ( pClient ); } - - epicsThreadSleep ( LOG_RESTART_DELAY ); + + epicsEventWaitWithTimeout ( pClient->shutdownNotify, LOG_RESTART_DELAY); epicsMutexMustLock ( pClient->mutex ); } @@ -505,14 +507,22 @@ logClientId epicsShareAPI logClientCreate ( pClient->shutdownConfirm = 0; epicsAtExit (logClientDestroy, (void*) pClient); - + pClient->stateChangeNotify = epicsEventCreate (epicsEventEmpty); if ( ! pClient->stateChangeNotify ) { epicsMutexDestroy ( pClient->mutex ); free ( pClient ); return NULL; } - + + pClient->shutdownNotify = epicsEventCreate (epicsEventEmpty); + if ( ! pClient->shutdownNotify ) { + epicsMutexDestroy ( pClient->mutex ); + epicsEventDestroy ( pClient->stateChangeNotify ); + free ( pClient ); + return NULL; + } + pClient->restartThreadId = epicsThreadCreate ( "logRestart", epicsThreadPriorityLow, epicsThreadGetStackSize(epicsThreadStackSmall), @@ -520,6 +530,7 @@ logClientId epicsShareAPI logClientCreate ( if ( pClient->restartThreadId == NULL ) { epicsMutexDestroy ( pClient->mutex ); epicsEventDestroy ( pClient->stateChangeNotify ); + epicsEventDestroy ( pClient->shutdownNotify ); free (pClient); fprintf(stderr, "log client: unable to start log client connection watch dog thread\n"); return NULL; From 0a3427c835e367792dd3419bc2a5bc1aea02386a Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Wed, 28 Aug 2019 09:29:57 +0200 Subject: [PATCH 03/23] do not discard unsent messages when log server has closed connection, instead try to send them after reconnect --- modules/libcom/src/log/logClient.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 96382a2eb..75984404c 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -85,8 +85,6 @@ static void logClientClose ( logClient *pClient ) pClient->sock = INVALID_SOCKET; } - pClient->nextMsgIndex = 0u; - memset ( pClient->msgBuf, '\0', sizeof ( pClient->msgBuf ) ); pClient->connected = 0u; /* From 709208ef5cd4db2764875175aacd94fd500e984a Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Wed, 28 Aug 2019 11:41:12 +0200 Subject: [PATCH 04/23] elimitate duplicate code in logClient --- modules/libcom/src/log/logClient.c | 62 +++++++----------------------- 1 file changed, 14 insertions(+), 48 deletions(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 75984404c..90fde98b5 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -174,57 +174,23 @@ static void sendMessageChunk(logClient * pClient, const char * message) { unsigned msgBufBytesLeft = sizeof ( pClient->msgBuf ) - pClient->nextMsgIndex; - if ( strSize > msgBufBytesLeft ) { - int status; - - if ( ! pClient->connected ) { - break; - } - - if ( msgBufBytesLeft > 0u ) { - memcpy ( & pClient->msgBuf[pClient->nextMsgIndex], - message, msgBufBytesLeft ); - pClient->nextMsgIndex += msgBufBytesLeft; - strSize -= msgBufBytesLeft; - message += msgBufBytesLeft; - } - - status = send ( pClient->sock, pClient->msgBuf, - pClient->nextMsgIndex, 0 ); - if ( status > 0 ) { - unsigned nSent = (unsigned) status; - if ( nSent < pClient->nextMsgIndex ) { - unsigned newNextMsgIndex = pClient->nextMsgIndex - nSent; - memmove ( pClient->msgBuf, & pClient->msgBuf[nSent], - newNextMsgIndex ); - pClient->nextMsgIndex = newNextMsgIndex; - } - else { - pClient->nextMsgIndex = 0u; - } - } - else { - if ( ! pClient->shutdown ) { - char sockErrBuf[64]; - if ( status ) { - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - } - else { - strcpy ( sockErrBuf, "server initiated disconnect" ); - } - fprintf ( stderr, "log client: lost contact with log server at \"%s\" because \"%s\"\n", - pClient->name, sockErrBuf ); - } - logClientClose ( pClient ); - break; - } + if ( msgBufBytesLeft < strSize && pClient->nextMsgIndex != 0u && pClient->connected) + { + /* buffer is full, thus flush it */ + logClientFlush ( pClient ); + msgBufBytesLeft = sizeof ( pClient->msgBuf ) - pClient->nextMsgIndex; } - else { - memcpy ( & pClient->msgBuf[pClient->nextMsgIndex], - message, strSize ); - pClient->nextMsgIndex += strSize; + if ( msgBufBytesLeft == 0u ) { + fprintf ( stderr, "log client: messages to \"%s\" are lost\n", + pClient->name ); break; } + if ( msgBufBytesLeft > strSize) msgBufBytesLeft = strSize; + memcpy ( & pClient->msgBuf[pClient->nextMsgIndex], + message, msgBufBytesLeft ); + pClient->nextMsgIndex += msgBufBytesLeft; + strSize -= msgBufBytesLeft; + message += msgBufBytesLeft; } } From 59aa9cfe746b3fc08d7b94b82f47973f6c5ed92c Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Wed, 28 Aug 2019 15:15:19 +0200 Subject: [PATCH 05/23] avoid needless memmove calls --- modules/libcom/src/log/logClient.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 90fde98b5..203f29dd3 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -219,6 +219,8 @@ void epicsShareAPI logClientSend ( logClientId id, const char * message ) void epicsShareAPI logClientFlush ( logClientId id ) { + unsigned nSent = 0u; + logClient * pClient = ( logClient * ) id; if ( ! pClient ) { @@ -227,20 +229,11 @@ void epicsShareAPI logClientFlush ( logClientId id ) epicsMutexMustLock ( pClient->mutex ); - while ( pClient->nextMsgIndex && pClient->connected ) { - int status = send ( pClient->sock, pClient->msgBuf, - pClient->nextMsgIndex, 0 ); + while ( nSent < pClient->nextMsgIndex && pClient->connected ) { + int status = send ( pClient->sock, pClient->msgBuf + nSent, + pClient->nextMsgIndex - nSent, 0 ); if ( status > 0 ) { - unsigned nSent = (unsigned) status; - if ( nSent < pClient->nextMsgIndex ) { - unsigned newNextMsgIndex = pClient->nextMsgIndex - nSent; - memmove ( pClient->msgBuf, & pClient->msgBuf[nSent], - newNextMsgIndex ); - pClient->nextMsgIndex = newNextMsgIndex; - } - else { - pClient->nextMsgIndex = 0u; - } + nSent += (unsigned) status; } else { if ( ! pClient->shutdown ) { @@ -258,6 +251,11 @@ void epicsShareAPI logClientFlush ( logClientId id ) break; } } + pClient->nextMsgIndex -= nSent; + if ( nSent > 0 && pClient->nextMsgIndex > 0 ) { + memmove ( pClient->msgBuf, & pClient->msgBuf[nSent], + pClient->nextMsgIndex ); + } epicsMutexUnlock ( pClient->mutex ); } From 9df98c18386f1204fdf21a58f0f6dc1aae04126e Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Wed, 28 Aug 2019 15:23:00 +0200 Subject: [PATCH 06/23] send pending log messages directly after connecting --- modules/libcom/src/log/logClient.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 203f29dd3..743910fb8 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -223,7 +223,7 @@ void epicsShareAPI logClientFlush ( logClientId id ) logClient * pClient = ( logClient * ) id; - if ( ! pClient ) { + if ( ! pClient || ! pClient->connected ) { return; } @@ -419,12 +419,8 @@ static void logClientRestart ( logClientId id ) epicsMutexUnlock ( pClient->mutex ); - if ( isConn ) { - logClientFlush ( pClient ); - } - else { - logClientConnect ( pClient ); - } + if ( ! isConn ) logClientConnect ( pClient ); + logClientFlush ( pClient ); epicsEventWaitWithTimeout ( pClient->shutdownNotify, LOG_RESTART_DELAY); From 2b0161d9bfd8fc604942996d1812d245bf4a00f7 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Wed, 28 Aug 2019 15:29:23 +0200 Subject: [PATCH 07/23] no need to delay startup only because log server is currently not available --- modules/libcom/src/log/logClient.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 743910fb8..72a2e1364 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -54,7 +54,6 @@ typedef struct { } logClient; static const double LOG_RESTART_DELAY = 5.0; /* sec */ -static const double LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT = 5.0; /* sec */ static const double LOG_SERVER_SHUTDOWN_TIMEOUT = 30.0; /* sec */ /* @@ -438,9 +437,7 @@ static void logClientRestart ( logClientId id ) logClientId epicsShareAPI logClientCreate ( struct in_addr server_addr, unsigned short server_port) { - epicsTimeStamp begin, current; logClient *pClient; - double diff; pClient = calloc (1, sizeof (*pClient)); if (pClient==NULL) { @@ -494,28 +491,6 @@ logClientId epicsShareAPI logClientCreate ( return NULL; } - /* - * attempt to synchronize with circuit connect - */ - epicsTimeGetCurrent ( & begin ); - epicsMutexMustLock ( pClient->mutex ); - do { - epicsMutexUnlock ( pClient->mutex ); - epicsEventWaitWithTimeout ( - pClient->stateChangeNotify, - LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT / 10.0 ); - epicsTimeGetCurrent ( & current ); - diff = epicsTimeDiffInSeconds ( & current, & begin ); - epicsMutexMustLock ( pClient->mutex ); - } - while ( ! pClient->connected && diff < LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT ); - epicsMutexUnlock ( pClient->mutex ); - - if ( ! pClient->connected ) { - fprintf (stderr, "log client create: timed out synchronizing with circuit connect to \"%s\" after %.1f seconds\n", - pClient->name, LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT ); - } - return (void *) pClient; } From 49bf8bb5ec900c503f4c5df7f5f73df203503e7e Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Tue, 17 Sep 2019 11:59:02 +0200 Subject: [PATCH 08/23] removed unneeded include --- modules/libcom/src/log/logClient.c | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 72a2e1364..723f5d4be 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -25,7 +25,6 @@ #include "dbDefs.h" #include "epicsEvent.h" #include "iocLog.h" -#include "errlog.h" #include "epicsMutex.h" #include "epicsThread.h" #include "epicsTime.h" From d162337b9a52a860e6c4e079f2f147163d3f7226 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Tue, 17 Sep 2019 14:39:03 +0200 Subject: [PATCH 09/23] improve logClientShow to show unsent bytes on level 2 (and fix level 1) --- modules/libcom/src/log/logClient.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 723f5d4be..9b9e039b1 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -507,14 +507,21 @@ void epicsShareAPI logClientShow (logClientId id, unsigned level) printf ("log client: disconnected from log server at \"%s\"\n", pClient->name); } - if (level>1) { - printf ("log client: sock=%s, connect cycles = %u\n", + if (logClientPrefix) { + printf ("log client: prefix is \"%s\"\n", logClientPrefix); + } + + if (level>0) { + printf ("log client: sock %s, connect cycles = %u\n", pClient->sock==INVALID_SOCKET?"INVALID":"OK", pClient->connectCount); } - - if (logClientPrefix) { - printf ("log client: prefix is \"%s\"\n", logClientPrefix); + if (level>1) { + printf ("log client: %u bytes in buffer\n", pClient->nextMsgIndex); + if (pClient->nextMsgIndex) + printf("-------------------------\n" + "%.*s-------------------------\n", + (int)(pClient->nextMsgIndex), pClient->msgBuf); } } From 26f6f674be89f209606aeb447929e8146d43e230 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Tue, 17 Sep 2019 14:41:35 +0200 Subject: [PATCH 10/23] increase error message buffer size for long (Windows) error messges --- modules/libcom/src/log/logClient.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 9b9e039b1..3defa6baf 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -235,7 +235,7 @@ void epicsShareAPI logClientFlush ( logClientId id ) } else { if ( ! pClient->shutdown ) { - char sockErrBuf[64]; + char sockErrBuf[128]; if ( status ) { epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); } @@ -274,7 +274,7 @@ static void logClientMakeSock (logClient *pClient) */ pClient->sock = epicsSocketCreate ( AF_INET, SOCK_STREAM, 0 ); if ( pClient->sock == INVALID_SOCKET ) { - char sockErrBuf[64]; + char sockErrBuf[128]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf ( stderr, "log client: no socket error %s\n", @@ -326,7 +326,7 @@ static void logClientConnect (logClient *pClient) } else { if ( pClient->connFailStatus != errnoCpy && ! pClient->shutdown ) { - char sockErrBuf[64]; + char sockErrBuf[128]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf (stderr, @@ -352,7 +352,7 @@ static void logClientConnect (logClient *pClient) optval = TRUE; status = setsockopt (pClient->sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)); if (status<0) { - char sockErrBuf[64]; + char sockErrBuf[128]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf (stderr, "log client: unable to enable keepalive option because \"%s\"\n", sockErrBuf); @@ -364,7 +364,7 @@ static void logClientConnect (logClient *pClient) */ status = shutdown (pClient->sock, SHUT_RD); if (status < 0) { - char sockErrBuf[64]; + char sockErrBuf[128]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf (stderr, "%s:%d shutdown(%d,SHUT_RD) error was \"%s\"\n", @@ -385,7 +385,7 @@ static void logClientConnect (logClient *pClient) lingerval.l_linger = 60*5; status = setsockopt (pClient->sock, SOL_SOCKET, SO_LINGER, (char *) &lingerval, sizeof(lingerval)); if (status<0) { - char sockErrBuf[64]; + char sockErrBuf[128]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); fprintf (stderr, "log client: unable to set linger options because \"%s\"\n", sockErrBuf); From f85454a8d66e42503ae5295144ed2da8147ef4bc Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Tue, 17 Sep 2019 17:06:55 +0200 Subject: [PATCH 11/23] use dynamic debug flag for logClient --- modules/database/src/ioc/misc/dbCore.dbd | 3 +++ modules/libcom/src/log/logClient.c | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/modules/database/src/ioc/misc/dbCore.dbd b/modules/database/src/ioc/misc/dbCore.dbd index 51f9c9640..adde24e4f 100644 --- a/modules/database/src/ioc/misc/dbCore.dbd +++ b/modules/database/src/ioc/misc/dbCore.dbd @@ -33,3 +33,6 @@ variable(callbackParallelThreadsDefault,int) # Real-time operation variable(dbThreadRealtimeLock,int) + +# show logClient network activity +variable(logClientDebug,int) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 3defa6baf..19d79b617 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -21,7 +21,6 @@ #include #include -#define epicsExportSharedSymbols #include "dbDefs.h" #include "epicsEvent.h" #include "iocLog.h" @@ -32,9 +31,13 @@ #include "epicsAssert.h" #include "epicsExit.h" #include "epicsSignal.h" +#include "epicsExport.h" #include "logClient.h" +int logClientDebug = 0; +epicsExportAddress (int, logClientDebug); + typedef struct { char msgBuf[0x4000]; struct sockaddr_in addr; @@ -65,10 +68,10 @@ static char* logClientPrefix = NULL; */ static void logClientClose ( logClient *pClient ) { -# ifdef DEBUG + if (logClientDebug) { fprintf (stderr, "log client: lingering for connection close..."); fflush (stderr); -# endif + } /* * mutex on @@ -90,9 +93,8 @@ static void logClientClose ( logClient *pClient ) */ epicsMutexUnlock (pClient->mutex); -# ifdef DEBUG + if (logClientDebug) fprintf (stderr, "done\n"); -# endif } /* @@ -262,10 +264,10 @@ void epicsShareAPI logClientFlush ( logClientId id ) */ static void logClientMakeSock (logClient *pClient) { - -# ifdef DEBUG + if (logClientDebug) { fprintf (stderr, "log client: creating socket..."); -# endif + fflush (stderr); + } epicsMutexMustLock (pClient->mutex); @@ -283,10 +285,8 @@ static void logClientMakeSock (logClient *pClient) epicsMutexUnlock (pClient->mutex); -# ifdef DEBUG + if (logClientDebug) fprintf (stderr, "done\n"); -# endif - } /* From 6ffc9e17dacf7af450cdee2e3915cb73f317ef96 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Tue, 17 Sep 2019 17:34:16 +0200 Subject: [PATCH 12/23] ask logClient socket how many bytes are still in the send queue and don't discard them in case the connection turns out broken. --- modules/libcom/src/log/logClient.c | 83 +++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 19d79b617..44eaf7dab 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -49,6 +49,7 @@ typedef struct { epicsEventId shutdownNotify; unsigned connectCount; unsigned nextMsgIndex; + unsigned backlog; unsigned connected; unsigned shutdown; unsigned shutdownConfirm; @@ -194,6 +195,39 @@ static void sendMessageChunk(logClient * pClient, const char * message) { } } +/* + * epicsSockCountUnsentBytes () + * Should go to osd socket support + */ +#if defined (_WIN32) && WINVER >= _WIN32_WINNT_WIN10 +#include +#endif + +static int epicsSockCountUnsentBytes(SOCKET sock) { +#if defined (_WIN32) && WINVER >= _WIN32_WINNT_WIN10 +/* Windows 10 Version 1703 / Server 2016 */ +/* https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-tcp_info_v0 */ + DWORD infoVersion = 0, bytesReturned; + TCP_INFO_v0 tcpInfo; + int status; + if ((status = WSAIoctl(sock, SIO_TCP_INFO, &infoVersion, sizeof(infoVersion), + &tcpInfo, sizeof(tcpInfo), &bytesReturned, NULL, NULL)) == 0) + return tcpInfo.BytesInFlight; +#elif defined (SO_NWRITE) +/* macOS / iOS */ +/* https://www.unix.com/man-page/osx/2/setsockopt/ */ + int unsent; + if (getsockopt(sock, SOL_SOCKET, SO_NWRITE, &unsent) == 0) + return unsent; +#elif defined (TIOCOUTQ) +/* Linux */ +/* https://linux.die.net/man/7/tcp */ + int unsent; + if (ioctl(sock, TIOCOUTQ, &unsent) == 0) + return unsent; +#endif + return 0; +} /* * logClientSend () @@ -219,7 +253,8 @@ void epicsShareAPI logClientSend ( logClientId id, const char * message ) void epicsShareAPI logClientFlush ( logClientId id ) { - unsigned nSent = 0u; + unsigned nSent; + int status = 0; logClient * pClient = ( logClient * ) id; @@ -229,32 +264,32 @@ void epicsShareAPI logClientFlush ( logClientId id ) epicsMutexMustLock ( pClient->mutex ); + nSent = pClient->backlog; while ( nSent < pClient->nextMsgIndex && pClient->connected ) { - int status = send ( pClient->sock, pClient->msgBuf + nSent, + status = send ( pClient->sock, pClient->msgBuf + nSent, pClient->nextMsgIndex - nSent, 0 ); - if ( status > 0 ) { - nSent += (unsigned) status; - } - else { - if ( ! pClient->shutdown ) { - char sockErrBuf[128]; - if ( status ) { - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - } - else { - strcpy ( sockErrBuf, "server initiated disconnect" ); - } - fprintf ( stderr, "log client: lost contact with log server at \"%s\" because \"%s\"\n", - pClient->name, sockErrBuf ); - } - logClientClose ( pClient ); - break; - } + if ( status < 0 ) break; + nSent += status; } - pClient->nextMsgIndex -= nSent; - if ( nSent > 0 && pClient->nextMsgIndex > 0 ) { - memmove ( pClient->msgBuf, & pClient->msgBuf[nSent], - pClient->nextMsgIndex ); + + if ( status < 0 ) { + if ( ! pClient->shutdown ) { + char sockErrBuf[128]; + epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); + fprintf ( stderr, "log client: lost contact with log server at \"%s\" because \"%s\"\n", + pClient->name, sockErrBuf ); + } + pClient->backlog = 0; + logClientClose ( pClient ); + } + else if ( nSent > 0 && pClient->nextMsgIndex > 0 ) { + pClient->backlog = epicsSockCountUnsentBytes ( pClient->sock ); + nSent -= pClient->backlog; + if ( nSent > 0 ) { + memmove ( pClient->msgBuf, & pClient->msgBuf[nSent], + pClient->nextMsgIndex ); + pClient->nextMsgIndex -= nSent; + } } epicsMutexUnlock ( pClient->mutex ); } From 931054d4fd96d0896bb74c2765c731bbbcef7295 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Tue, 17 Sep 2019 17:45:33 +0200 Subject: [PATCH 13/23] cannot print sockets with %d in Windows, they are not small ints but maybe pointers. --- modules/libcom/src/log/logClient.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 44eaf7dab..762703417 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -402,8 +402,8 @@ static void logClientConnect (logClient *pClient) char sockErrBuf[128]; epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf (stderr, "%s:%d shutdown(%d,SHUT_RD) error was \"%s\"\n", - __FILE__, __LINE__, pClient->sock, sockErrBuf); + fprintf (stderr, "%s:%d shutdown(sock,SHUT_RD) error was \"%s\"\n", + __FILE__, __LINE__, sockErrBuf); /* not fatal (although it shouldn't happen) */ } From c9b670977d590fb95455c358ed5597599804d66a Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Wed, 18 Sep 2019 09:58:28 +0200 Subject: [PATCH 14/23] sending 0 bytes helps to detect broken connections on some systems (but is undefined behavior on Linux, fails on vxWorks and is a documented no-op on Windows) --- modules/libcom/src/log/logClient.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 762703417..6671d2785 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -272,6 +272,15 @@ void epicsShareAPI logClientFlush ( logClientId id ) nSent += status; } + if ( pClient->backlog > 0 && status >= 0 ) + { + /* On Linux send 0 bytes can detect EPIPE */ + /* NOOP on Windows, fails on vxWorks */ + errno = 0; + status = send ( pClient->sock, NULL, 0, 0 ); + if (!(errno == ECONNRESET || errno == EPIPE)) status = 0; + } + if ( status < 0 ) { if ( ! pClient->shutdown ) { char sockErrBuf[128]; From db3b160f4ec7eeb988aa585078740b1c2aa7f8a7 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Thu, 19 Sep 2019 08:54:19 +0200 Subject: [PATCH 15/23] fix wrong function name in comment --- modules/libcom/src/log/iocLog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/libcom/src/log/iocLog.c b/modules/libcom/src/log/iocLog.c index 8cb1349a1..c0fa33fa6 100644 --- a/modules/libcom/src/log/iocLog.c +++ b/modules/libcom/src/log/iocLog.c @@ -77,7 +77,7 @@ void epicsShareAPI epicsShareAPI iocLogFlush (void) } /* - * logClientDestroy() + * iocLogClientDestroy() */ static void iocLogClientDestroy (logClientId id) { From 64f540a64ffc3282d05b3a6b7274e63639f1116c Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Thu, 19 Sep 2019 10:44:36 +0200 Subject: [PATCH 16/23] moved logClientSendMessage and made it static --- modules/libcom/src/log/iocLog.c | 11 +++++++++++ modules/libcom/src/log/logClient.c | 10 ---------- modules/libcom/src/log/logClient.h | 1 - 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/modules/libcom/src/log/iocLog.c b/modules/libcom/src/log/iocLog.c index c0fa33fa6..ba78041c8 100644 --- a/modules/libcom/src/log/iocLog.c +++ b/modules/libcom/src/log/iocLog.c @@ -76,6 +76,16 @@ void epicsShareAPI epicsShareAPI iocLogFlush (void) } } +/* + * logClientSendMessage () + */ +static void logClientSendMessage ( logClientId id, const char * message ) +{ + if ( !iocLogDisable ) { + logClientSend (id, message); + } +} + /* * iocLogClientDestroy() */ @@ -149,3 +159,4 @@ logClientId epicsShareAPI logClientInit (void) { return iocLogClientInit (); } + diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 6671d2785..cd832b60c 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -569,16 +569,6 @@ void epicsShareAPI logClientShow (logClientId id, unsigned level) } } -/* - * logClientSendMessage (); deprecated - */ -void logClientSendMessage ( logClientId id, const char * message ) -{ - if ( !iocLogDisable ) { - logClientSend (id, message); - } -} - /* * iocLogPrefix() */ diff --git a/modules/libcom/src/log/logClient.h b/modules/libcom/src/log/logClient.h index 1797bbb20..3b3f63add 100644 --- a/modules/libcom/src/log/logClient.h +++ b/modules/libcom/src/log/logClient.h @@ -38,7 +38,6 @@ epicsShareFunc void epicsShareAPI iocLogPrefix(const char* prefix); /* deprecated interface; retained for backward compatibility */ /* note: implementations are in iocLog.c, not logClient.c */ epicsShareFunc logClientId epicsShareAPI logClientInit (void); -epicsShareFunc void logClientSendMessage (logClientId id, const char *message); #ifdef __cplusplus } From e28bb3b0e20fe0c18db5c7b9e36da19e95877dcd Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Thu, 19 Sep 2019 10:48:14 +0200 Subject: [PATCH 17/23] epicsSockCountUnsentBytes renamed to epicsSocketCountUnsentBytes --- modules/libcom/src/log/logClient.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index cd832b60c..28b933e02 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -196,14 +196,14 @@ static void sendMessageChunk(logClient * pClient, const char * message) { } /* - * epicsSockCountUnsentBytes () + * epicsSocketCountUnsentBytes () * Should go to osd socket support */ #if defined (_WIN32) && WINVER >= _WIN32_WINNT_WIN10 #include #endif -static int epicsSockCountUnsentBytes(SOCKET sock) { +static int epicsSocketCountUnsentBytes(SOCKET sock) { #if defined (_WIN32) && WINVER >= _WIN32_WINNT_WIN10 /* Windows 10 Version 1703 / Server 2016 */ /* https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-tcp_info_v0 */ @@ -292,7 +292,7 @@ void epicsShareAPI logClientFlush ( logClientId id ) logClientClose ( pClient ); } else if ( nSent > 0 && pClient->nextMsgIndex > 0 ) { - pClient->backlog = epicsSockCountUnsentBytes ( pClient->sock ); + pClient->backlog = epicsSocketCountUnsentBytes ( pClient->sock ); nSent -= pClient->backlog; if ( nSent > 0 ) { memmove ( pClient->msgBuf, & pClient->msgBuf[nSent], From 752ec12261cf10155754534c3de8ea7bdfda5e54 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Thu, 19 Sep 2019 11:42:04 +0200 Subject: [PATCH 18/23] bugfix: memmove'ed to much --- modules/libcom/src/log/logClient.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 28b933e02..4e647bd83 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -294,10 +294,10 @@ void epicsShareAPI logClientFlush ( logClientId id ) else if ( nSent > 0 && pClient->nextMsgIndex > 0 ) { pClient->backlog = epicsSocketCountUnsentBytes ( pClient->sock ); nSent -= pClient->backlog; - if ( nSent > 0 ) { + pClient->nextMsgIndex -= nSent; + if ( nSent > 0 && pClient->nextMsgIndex > 0 ) { memmove ( pClient->msgBuf, & pClient->msgBuf[nSent], pClient->nextMsgIndex ); - pClient->nextMsgIndex -= nSent; } } epicsMutexUnlock ( pClient->mutex ); From 1718647121799f44d0a2c9a624635d2d8f2077fa Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Thu, 19 Sep 2019 12:08:45 +0200 Subject: [PATCH 19/23] epicsSocketCountUnsentBytes returns -1 on failure --- modules/libcom/src/log/logClient.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 4e647bd83..476634c5f 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -226,7 +226,7 @@ static int epicsSocketCountUnsentBytes(SOCKET sock) { if (ioctl(sock, TIOCOUTQ, &unsent) == 0) return unsent; #endif - return 0; + return -1; } /* @@ -292,8 +292,11 @@ void epicsShareAPI logClientFlush ( logClientId id ) logClientClose ( pClient ); } else if ( nSent > 0 && pClient->nextMsgIndex > 0 ) { - pClient->backlog = epicsSocketCountUnsentBytes ( pClient->sock ); - nSent -= pClient->backlog; + int backlog = epicsSocketCountUnsentBytes ( pClient->sock ); + if (backlog >= 0) { + pClient->backlog = backlog; + nSent -= backlog; + } pClient->nextMsgIndex -= nSent; if ( nSent > 0 && pClient->nextMsgIndex > 0 ) { memmove ( pClient->msgBuf, & pClient->msgBuf[nSent], From cf121f1c14a96b9a3171e5fd46d991cbffa7386b Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Mon, 23 Sep 2019 10:54:17 +0200 Subject: [PATCH 20/23] fix bug from commit f85454. Apparently epicsExportSharedSymbols is needed even though epicsExport.h is included --- modules/libcom/src/log/logClient.c | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 476634c5f..ee92c27c4 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -21,6 +21,7 @@ #include #include +#define epicsExportSharedSymbols #include "dbDefs.h" #include "epicsEvent.h" #include "iocLog.h" From 46912d55166f1664c947e14e3efdd71f6058880e Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Mon, 23 Sep 2019 11:10:32 +0200 Subject: [PATCH 21/23] renamed epicsSocketCountUnsentBytes to epicsSocketUnsentCount and moved it to osi/os/ --- modules/libcom/src/log/logClient.c | 36 +------------------ modules/libcom/src/osi/Makefile | 1 + .../src/osi/os/Darwin/osdSockUnsentCount.c | 17 +++++++++ .../src/osi/os/Linux/osdSockUnsentCount.c | 18 ++++++++++ .../src/osi/os/WIN32/osdSockUnsentCount.c | 25 +++++++++++++ .../src/osi/os/default/osdSockUnsentCount.c | 14 ++++++++ .../src/osi/os/iOS/osdSockUnsentCount.c | 17 +++++++++ modules/libcom/src/osi/osiSock.h | 6 ++++ 8 files changed, 99 insertions(+), 35 deletions(-) create mode 100644 modules/libcom/src/osi/os/Darwin/osdSockUnsentCount.c create mode 100644 modules/libcom/src/osi/os/Linux/osdSockUnsentCount.c create mode 100644 modules/libcom/src/osi/os/WIN32/osdSockUnsentCount.c create mode 100644 modules/libcom/src/osi/os/default/osdSockUnsentCount.c create mode 100644 modules/libcom/src/osi/os/iOS/osdSockUnsentCount.c diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index ee92c27c4..73664ff76 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -196,40 +196,6 @@ static void sendMessageChunk(logClient * pClient, const char * message) { } } -/* - * epicsSocketCountUnsentBytes () - * Should go to osd socket support - */ -#if defined (_WIN32) && WINVER >= _WIN32_WINNT_WIN10 -#include -#endif - -static int epicsSocketCountUnsentBytes(SOCKET sock) { -#if defined (_WIN32) && WINVER >= _WIN32_WINNT_WIN10 -/* Windows 10 Version 1703 / Server 2016 */ -/* https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-tcp_info_v0 */ - DWORD infoVersion = 0, bytesReturned; - TCP_INFO_v0 tcpInfo; - int status; - if ((status = WSAIoctl(sock, SIO_TCP_INFO, &infoVersion, sizeof(infoVersion), - &tcpInfo, sizeof(tcpInfo), &bytesReturned, NULL, NULL)) == 0) - return tcpInfo.BytesInFlight; -#elif defined (SO_NWRITE) -/* macOS / iOS */ -/* https://www.unix.com/man-page/osx/2/setsockopt/ */ - int unsent; - if (getsockopt(sock, SOL_SOCKET, SO_NWRITE, &unsent) == 0) - return unsent; -#elif defined (TIOCOUTQ) -/* Linux */ -/* https://linux.die.net/man/7/tcp */ - int unsent; - if (ioctl(sock, TIOCOUTQ, &unsent) == 0) - return unsent; -#endif - return -1; -} - /* * logClientSend () */ @@ -293,7 +259,7 @@ void epicsShareAPI logClientFlush ( logClientId id ) logClientClose ( pClient ); } else if ( nSent > 0 && pClient->nextMsgIndex > 0 ) { - int backlog = epicsSocketCountUnsentBytes ( pClient->sock ); + int backlog = epicsSocketUnsentCount ( pClient->sock ); if (backlog >= 0) { pClient->backlog = backlog; nSent -= backlog; diff --git a/modules/libcom/src/osi/Makefile b/modules/libcom/src/osi/Makefile index ecbf4c23b..71d8c3d73 100644 --- a/modules/libcom/src/osi/Makefile +++ b/modules/libcom/src/osi/Makefile @@ -86,6 +86,7 @@ endif Com_SRCS += osdSock.c Com_SRCS += osdSockAddrReuse.cpp +Com_SRCS += osdSockUnsentCount.c Com_SRCS += osiSock.c Com_SRCS += systemCallIntMech.cpp Com_SRCS += epicsSocketConvertErrnoToString.cpp diff --git a/modules/libcom/src/osi/os/Darwin/osdSockUnsentCount.c b/modules/libcom/src/osi/os/Darwin/osdSockUnsentCount.c new file mode 100644 index 000000000..00ef550bd --- /dev/null +++ b/modules/libcom/src/osi/os/Darwin/osdSockUnsentCount.c @@ -0,0 +1,17 @@ +/*************************************************************************\ +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +#include "osiSock.h" + +/* + * epicsSocketUnsentCount () + * See https://www.unix.com/man-page/osx/2/setsockopt + */ +int epicsSocketUnsentCount(SOCKET sock) { + int unsent; + if (getsockopt(sock, SOL_SOCKET, SO_NWRITE, &unsent) == 0) + return unsent; + return -1; +} diff --git a/modules/libcom/src/osi/os/Linux/osdSockUnsentCount.c b/modules/libcom/src/osi/os/Linux/osdSockUnsentCount.c new file mode 100644 index 000000000..6f6cbf0fe --- /dev/null +++ b/modules/libcom/src/osi/os/Linux/osdSockUnsentCount.c @@ -0,0 +1,18 @@ +/*************************************************************************\ +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +#include +#include "osiSock.h" + +/* + * epicsSocketUnsentCount () + * See https://linux.die.net/man/7/tcp + */ +int epicsSocketUnsentCount(SOCKET sock) { + int unsent; + if (ioctl(sock, SIOCOUTQ, &unsent) == 0) + return unsent; + return -1; +} diff --git a/modules/libcom/src/osi/os/WIN32/osdSockUnsentCount.c b/modules/libcom/src/osi/os/WIN32/osdSockUnsentCount.c new file mode 100644 index 000000000..c2045bc79 --- /dev/null +++ b/modules/libcom/src/osi/os/WIN32/osdSockUnsentCount.c @@ -0,0 +1,25 @@ +/*************************************************************************\ +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +#define epicsExportSharedSymbols +#include "osiSock.h" +#include + +/* + * epicsSocketUnsentCount () + * See https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-tcp_info_v0 + */ +int epicsSocketUnsentCount(SOCKET sock) { +#if defined (_WIN32) && WINVER >= _WIN32_WINNT_WIN10 +/* Windows 10 Version 1703 / Server 2016 */ + DWORD infoVersion = 0, bytesReturned; + TCP_INFO_v0 tcpInfo; + int status; + if ((status = WSAIoctl(sock, SIO_TCP_INFO, &infoVersion, sizeof(infoVersion), + &tcpInfo, sizeof(tcpInfo), &bytesReturned, NULL, NULL)) == 0) + return tcpInfo.BytesInFlight; +#endif + return -1; +} diff --git a/modules/libcom/src/osi/os/default/osdSockUnsentCount.c b/modules/libcom/src/osi/os/default/osdSockUnsentCount.c new file mode 100644 index 000000000..61094c710 --- /dev/null +++ b/modules/libcom/src/osi/os/default/osdSockUnsentCount.c @@ -0,0 +1,14 @@ +/*************************************************************************\ +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +#include "osiSock.h" + +/* + * epicsSocketUnsentCount () + */ +int epicsSocketUnsentCount(SOCKET sock) { + /* not implemented */ + return -1; +} diff --git a/modules/libcom/src/osi/os/iOS/osdSockUnsentCount.c b/modules/libcom/src/osi/os/iOS/osdSockUnsentCount.c new file mode 100644 index 000000000..00ef550bd --- /dev/null +++ b/modules/libcom/src/osi/os/iOS/osdSockUnsentCount.c @@ -0,0 +1,17 @@ +/*************************************************************************\ +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +#include "osiSock.h" + +/* + * epicsSocketUnsentCount () + * See https://www.unix.com/man-page/osx/2/setsockopt + */ +int epicsSocketUnsentCount(SOCKET sock) { + int unsent; + if (getsockopt(sock, SOL_SOCKET, SO_NWRITE, &unsent) == 0) + return unsent; + return -1; +} diff --git a/modules/libcom/src/osi/osiSock.h b/modules/libcom/src/osi/osiSock.h index 061619e89..e1c2de881 100644 --- a/modules/libcom/src/osi/osiSock.h +++ b/modules/libcom/src/osi/osiSock.h @@ -52,6 +52,12 @@ enum epicsSocketSystemCallInterruptMechanismQueryInfo { epicsShareFunc enum epicsSocketSystemCallInterruptMechanismQueryInfo epicsSocketSystemCallInterruptMechanismQuery (); +/* + * Some systems (e.g Linux and Windows 10) allow to check the amount + * of unsent data in the output queue. + * Returns -1 if the information is not available. + */ +epicsShareFunc int epicsSocketUnsentCount(SOCKET sock); /* * convert socket address to ASCII in this order From 4bb81654d60a5d343aeee1aa1ac8276c9ab43f75 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Fri, 4 Oct 2019 14:32:07 +0200 Subject: [PATCH 22/23] use EPICS_PRIVATE_API macro and fix bug with darwin/ios --- modules/libcom/src/log/logClient.c | 1 + modules/libcom/src/osi/os/Darwin/osdSockUnsentCount.c | 4 +++- modules/libcom/src/osi/os/Linux/osdSockUnsentCount.c | 1 + modules/libcom/src/osi/os/WIN32/osdSockUnsentCount.c | 1 + modules/libcom/src/osi/os/default/osdSockUnsentCount.c | 1 + modules/libcom/src/osi/os/iOS/osdSockUnsentCount.c | 4 +++- modules/libcom/src/osi/osiSock.h | 2 ++ 7 files changed, 12 insertions(+), 2 deletions(-) diff --git a/modules/libcom/src/log/logClient.c b/modules/libcom/src/log/logClient.c index 73664ff76..9a09ef7b7 100644 --- a/modules/libcom/src/log/logClient.c +++ b/modules/libcom/src/log/logClient.c @@ -21,6 +21,7 @@ #include #include +#define EPICS_PRIVATE_API #define epicsExportSharedSymbols #include "dbDefs.h" #include "epicsEvent.h" diff --git a/modules/libcom/src/osi/os/Darwin/osdSockUnsentCount.c b/modules/libcom/src/osi/os/Darwin/osdSockUnsentCount.c index 00ef550bd..20bd82b14 100644 --- a/modules/libcom/src/osi/os/Darwin/osdSockUnsentCount.c +++ b/modules/libcom/src/osi/os/Darwin/osdSockUnsentCount.c @@ -3,6 +3,7 @@ * in file LICENSE that is included with this distribution. \*************************************************************************/ +#define EPICS_PRIVATE_API #include "osiSock.h" /* @@ -11,7 +12,8 @@ */ int epicsSocketUnsentCount(SOCKET sock) { int unsent; - if (getsockopt(sock, SOL_SOCKET, SO_NWRITE, &unsent) == 0) + socklen_t len = sizeof(unsent); + if (getsockopt(sock, SOL_SOCKET, SO_NWRITE, &unsent, &len) == 0) return unsent; return -1; } diff --git a/modules/libcom/src/osi/os/Linux/osdSockUnsentCount.c b/modules/libcom/src/osi/os/Linux/osdSockUnsentCount.c index 6f6cbf0fe..3c0a8f915 100644 --- a/modules/libcom/src/osi/os/Linux/osdSockUnsentCount.c +++ b/modules/libcom/src/osi/os/Linux/osdSockUnsentCount.c @@ -4,6 +4,7 @@ \*************************************************************************/ #include +#define EPICS_PRIVATE_API #include "osiSock.h" /* diff --git a/modules/libcom/src/osi/os/WIN32/osdSockUnsentCount.c b/modules/libcom/src/osi/os/WIN32/osdSockUnsentCount.c index c2045bc79..fe68ead01 100644 --- a/modules/libcom/src/osi/os/WIN32/osdSockUnsentCount.c +++ b/modules/libcom/src/osi/os/WIN32/osdSockUnsentCount.c @@ -4,6 +4,7 @@ \*************************************************************************/ #define epicsExportSharedSymbols +#define EPICS_PRIVATE_API #include "osiSock.h" #include diff --git a/modules/libcom/src/osi/os/default/osdSockUnsentCount.c b/modules/libcom/src/osi/os/default/osdSockUnsentCount.c index 61094c710..ef01e9b24 100644 --- a/modules/libcom/src/osi/os/default/osdSockUnsentCount.c +++ b/modules/libcom/src/osi/os/default/osdSockUnsentCount.c @@ -3,6 +3,7 @@ * in file LICENSE that is included with this distribution. \*************************************************************************/ +#define EPICS_PRIVATE_API #include "osiSock.h" /* diff --git a/modules/libcom/src/osi/os/iOS/osdSockUnsentCount.c b/modules/libcom/src/osi/os/iOS/osdSockUnsentCount.c index 00ef550bd..20bd82b14 100644 --- a/modules/libcom/src/osi/os/iOS/osdSockUnsentCount.c +++ b/modules/libcom/src/osi/os/iOS/osdSockUnsentCount.c @@ -3,6 +3,7 @@ * in file LICENSE that is included with this distribution. \*************************************************************************/ +#define EPICS_PRIVATE_API #include "osiSock.h" /* @@ -11,7 +12,8 @@ */ int epicsSocketUnsentCount(SOCKET sock) { int unsent; - if (getsockopt(sock, SOL_SOCKET, SO_NWRITE, &unsent) == 0) + socklen_t len = sizeof(unsent); + if (getsockopt(sock, SOL_SOCKET, SO_NWRITE, &unsent, &len) == 0) return unsent; return -1; } diff --git a/modules/libcom/src/osi/osiSock.h b/modules/libcom/src/osi/osiSock.h index e1c2de881..6e3b053c5 100644 --- a/modules/libcom/src/osi/osiSock.h +++ b/modules/libcom/src/osi/osiSock.h @@ -52,12 +52,14 @@ enum epicsSocketSystemCallInterruptMechanismQueryInfo { epicsShareFunc enum epicsSocketSystemCallInterruptMechanismQueryInfo epicsSocketSystemCallInterruptMechanismQuery (); +#ifdef EPICS_PRIVATE_API /* * Some systems (e.g Linux and Windows 10) allow to check the amount * of unsent data in the output queue. * Returns -1 if the information is not available. */ epicsShareFunc int epicsSocketUnsentCount(SOCKET sock); +#endif /* * convert socket address to ASCII in this order From 5e6226e595975753f3f7a256982c0d77f6643394 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 24 Oct 2019 19:15:31 -0700 Subject: [PATCH 23/23] osdSockUnsentCount.c check for existance of SIO_TCP_INFO --- modules/libcom/src/osi/os/WIN32/osdSockUnsentCount.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/libcom/src/osi/os/WIN32/osdSockUnsentCount.c b/modules/libcom/src/osi/os/WIN32/osdSockUnsentCount.c index fe68ead01..3f4ab3eee 100644 --- a/modules/libcom/src/osi/os/WIN32/osdSockUnsentCount.c +++ b/modules/libcom/src/osi/os/WIN32/osdSockUnsentCount.c @@ -13,7 +13,7 @@ * See https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-tcp_info_v0 */ int epicsSocketUnsentCount(SOCKET sock) { -#if defined (_WIN32) && WINVER >= _WIN32_WINNT_WIN10 +#ifdef SIO_TCP_INFO /* Windows 10 Version 1703 / Server 2016 */ DWORD infoVersion = 0, bytesReturned; TCP_INFO_v0 tcpInfo;