commit d0e831 was wrong
This commit is contained in:
@@ -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)
|
||||
{
|
||||
errlogRemoveListener (logClientSendMessage);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ typedef struct {
|
||||
SOCKET sock;
|
||||
epicsThreadId restartThreadId;
|
||||
epicsEventId stateChangeNotify;
|
||||
epicsEventId shutdownNotify;
|
||||
unsigned connectCount;
|
||||
unsigned nextMsgIndex;
|
||||
unsigned connected;
|
||||
@@ -53,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 */
|
||||
|
||||
/*
|
||||
@@ -84,8 +84,6 @@ static void logClientClose ( logClient *pClient )
|
||||
pClient->sock = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
pClient->nextMsgIndex = 0u;
|
||||
memset ( pClient->msgBuf, '\0', sizeof ( pClient->msgBuf ) );
|
||||
pClient->connected = 0u;
|
||||
|
||||
/*
|
||||
@@ -113,6 +111,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 =
|
||||
@@ -154,13 +153,11 @@ static void logClientDestroy (logClientId id)
|
||||
return;
|
||||
}
|
||||
|
||||
errlogRemoveListeners ( logClientSendMessage, (void *) pClient );
|
||||
|
||||
logClientClose ( pClient );
|
||||
|
||||
epicsMutexDestroy ( pClient->mutex );
|
||||
|
||||
epicsEventDestroy ( pClient->stateChangeNotify );
|
||||
epicsEventDestroy ( pClient->shutdownNotify );
|
||||
|
||||
free ( pClient );
|
||||
}
|
||||
@@ -176,57 +173,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,28 +218,38 @@ void epicsShareAPI logClientSend ( logClientId id, const char * message )
|
||||
|
||||
void epicsShareAPI logClientFlush ( logClientId id )
|
||||
{
|
||||
unsigned nSent = 0u;
|
||||
|
||||
logClient * pClient = ( logClient * ) id;
|
||||
|
||||
if ( ! pClient ) {
|
||||
if ( ! pClient || ! pClient->connected ) {
|
||||
return;
|
||||
}
|
||||
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
|
||||
while ( pClient->nextMsgIndex && pClient->connected ) {
|
||||
int status = send ( pClient->sock, pClient->msgBuf,
|
||||
pClient->nextMsgIndex, 0 );
|
||||
while (1) {
|
||||
struct timeval timeout = { 0, 0 };
|
||||
fd_set set;
|
||||
char buffer[256];
|
||||
|
||||
FD_ZERO ( &set );
|
||||
FD_SET ( pClient->sock, &set );
|
||||
if ( select ( pClient->sock + 1, &set, NULL, NULL, &timeout ) == 0)
|
||||
break;
|
||||
if ( recv ( pClient->sock, buffer, sizeof ( buffer ), 0 ) == 0 ) {
|
||||
fprintf ( stderr, "log client: connection closed by server \"%s\"\n",
|
||||
pClient->name );
|
||||
logClientClose ( pClient );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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 ) {
|
||||
@@ -294,6 +267,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 );
|
||||
}
|
||||
|
||||
@@ -398,20 +376,6 @@ static void logClientConnect (logClient *pClient)
|
||||
fprintf (stderr, "log client: unable to enable keepalive option because \"%s\"\n", sockErrBuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* we don't need full-duplex (clients only write), so we shutdown
|
||||
* the read end of our socket
|
||||
*/
|
||||
status = shutdown (pClient->sock, SHUT_RD);
|
||||
if (status < 0) {
|
||||
char sockErrBuf[64];
|
||||
epicsSocketConvertErrnoToString (
|
||||
sockErrBuf, sizeof ( sockErrBuf ) );
|
||||
fprintf (stderr, "%s:%d shutdown(%d,SHUT_RD) error was \"%s\"\n",
|
||||
__FILE__, __LINE__, pClient->sock, sockErrBuf);
|
||||
/* not fatal (although it shouldn't happen) */
|
||||
}
|
||||
|
||||
/*
|
||||
* set how long we will wait for the TCP state machine
|
||||
* to clean up when we issue a close(). This
|
||||
@@ -457,14 +421,10 @@ static void logClientRestart ( logClientId id )
|
||||
|
||||
epicsMutexUnlock ( pClient->mutex );
|
||||
|
||||
if ( isConn ) {
|
||||
logClientFlush ( pClient );
|
||||
}
|
||||
else {
|
||||
logClientConnect ( pClient );
|
||||
}
|
||||
|
||||
epicsThreadSleep ( LOG_RESTART_DELAY );
|
||||
if ( ! isConn ) logClientConnect ( pClient );
|
||||
logClientFlush ( pClient );
|
||||
|
||||
epicsEventWaitWithTimeout ( pClient->shutdownNotify, LOG_RESTART_DELAY);
|
||||
|
||||
epicsMutexMustLock ( pClient->mutex );
|
||||
}
|
||||
@@ -480,9 +440,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) {
|
||||
@@ -507,14 +465,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),
|
||||
@@ -522,35 +488,12 @@ 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 );
|
||||
}
|
||||
|
||||
errlogAddListener ( logClientSendMessage, (void *) pClient );
|
||||
|
||||
return (void *) pClient;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user