From 27838589a5cf0b3659eed6bb7668f5b38ef8ef54 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 27 Apr 2000 04:26:15 +0000 Subject: [PATCH] Added connection opening timeout handling --- WINGs/ChangeLog | 3 ++ WINGs/WUtil.h | 29 ++++++++++++++-- WINGs/connection.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++------- WINGs/hashtable.c | 2 +- 4 files changed, 116 insertions(+), 17 deletions(-) diff --git a/WINGs/ChangeLog b/WINGs/ChangeLog index 105aeb45..918efc44 100644 --- a/WINGs/ChangeLog +++ b/WINGs/ChangeLog @@ -6,6 +6,9 @@ changes since wmaker 0.62.0: - added clientdata to WMFindInBag - removed SetWindowInitialSize() - added SetWindowAspectRatio() +- added initial timeout when establishing a connection. +- added WMSetConnectionDefaultTimeout() and WMSetConnectionOpenTimeout(); +- added WMGetConnectionTimeoutState() changes since wmaker 0.61.1: ............................ diff --git a/WINGs/WUtil.h b/WINGs/WUtil.h index 5abedf3c..e6507850 100644 --- a/WINGs/WUtil.h +++ b/WINGs/WUtil.h @@ -96,11 +96,20 @@ typedef enum { WCInProgress, WCFailed, WCConnected, + WCTimedOut, WCDied, WCClosed } WMConnectionState; +/* The possible states for connection timeouts */ +typedef enum { + WCTNone=0, + WCTWhileOpening, + WCTWhileSending +} WMConnectionTimeoutState; + + enum { WBNotFound = INT_MIN /* element was not found in bag */ @@ -117,10 +126,10 @@ typedef struct W_Host WMHost; typedef struct W_Connection WMConnection; - + typedef void WMFreeDataProc(void *data); - + typedef struct { int position; @@ -310,7 +319,7 @@ extern const WMHashTableCallbacks WMIntHashCallbacks; extern const WMHashTableCallbacks WMStringHashCallbacks; /* keys are strings. Strings will be copied with wstrdup() - * and freed with free() */ + * and freed with wfree() */ extern const WMHashTableCallbacks WMStringPointerHashCallbacks; /* keys are strings, bug they are not copied */ @@ -703,6 +712,20 @@ int WMGetConnectionSocket(WMConnection *cPtr); WMConnectionState WMGetConnectionState(WMConnection *cPtr); +WMConnectionTimeoutState WMGetConnectionTimeoutState(WMConnection *cPtr); + +/* + * Passing timeout==0 in the SetTimeout functions below, will reset that + * timeout to its default value. + */ + +/* The default timeout inherited by all WMConnection operations, if none set */ +void WMSetConnectionDefaultTimeout(unsigned int timeout); + +/* Global timeout for all WMConnection objects, for opening a new connection */ +void WMSetConnectionOpenTimeout(unsigned int timeout); + +/* Connection specific timeout for sending out data */ void WMSetConnectionSendTimeout(WMConnection *cPtr, unsigned int timeout); diff --git a/WINGs/connection.c b/WINGs/connection.c index 93412ae8..d6670cc6 100644 --- a/WINGs/connection.c +++ b/WINGs/connection.c @@ -77,10 +77,14 @@ #define DEF_TIMEOUT 600 /* 600 seconds == 10 minutes */ + int WCErrorCode = 0; static Bool SigInitialized = False; +static unsigned int DefaultTimeout = DEF_TIMEOUT; +static unsigned int OpenTimeout = DEF_TIMEOUT; + typedef struct TimeoutData { @@ -106,8 +110,10 @@ typedef struct W_Connection { unsigned bufPos; TimeoutData sendTimeout; + TimeoutData openTimeout; WMConnectionState state; + WMConnectionTimeoutState timeoutState; char *address; char *service; @@ -121,7 +127,6 @@ typedef struct W_Connection { - static void clearOutputQueue(WMConnection *cPtr) /*FOLD00*/ { @@ -137,20 +142,48 @@ clearOutputQueue(WMConnection *cPtr) /*FOLD00*/ static void +openTimeout(void *cdata) /*FOLD00*/ +{ + WMConnection *cPtr = (WMConnection*) cdata; + + cPtr->openTimeout.handler = NULL; + if (cPtr->handler.write) { + WMDeleteInputHandler(cPtr->handler.write); + cPtr->handler.write = NULL; + } + if (cPtr->state != WCConnected) { + cPtr->state = WCTimedOut; + cPtr->timeoutState = WCTWhileOpening; + if (cPtr->delegate && cPtr->delegate->didTimeout) { + (*cPtr->delegate->didTimeout)(cPtr->delegate, cPtr); + } else { + WMCloseConnection(cPtr); + cPtr->state = WCTimedOut; /* the above set state to WCClosed */ + } + } +} + + +static void sendTimeout(void *cdata) /*FOLD00*/ { WMConnection *cPtr = (WMConnection*) cdata; - TimeoutData *tPtr = &cPtr->sendTimeout; - tPtr->handler = NULL; + cPtr->sendTimeout.handler = NULL; if (cPtr->handler.write) { WMDeleteInputHandler(cPtr->handler.write); cPtr->handler.write = NULL; } if (WMGetBagItemCount(cPtr->outputQueue)>0) { clearOutputQueue(cPtr); - if (cPtr->delegate && cPtr->delegate->didTimeout) + cPtr->state = WCTimedOut; + cPtr->timeoutState = WCTWhileSending; + if (cPtr->delegate && cPtr->delegate->didTimeout) { (*cPtr->delegate->didTimeout)(cPtr->delegate, cPtr); + } else { + WMCloseConnection(cPtr); + cPtr->state = WCTimedOut; /* the above set state to WCClosed */ + } } } @@ -185,6 +218,11 @@ inputHandler(int fd, int mask, void *clientData) /*FOLD00*/ cPtr->handler.write = NULL; } + if (cPtr->openTimeout.handler) { + WMDeleteTimerHandler(cPtr->openTimeout.handler); + cPtr->openTimeout.handler = NULL; + } + if (cPtr->delegate && cPtr->delegate->didInitialize) (*cPtr->delegate->didInitialize)(cPtr->delegate, cPtr); @@ -329,11 +367,14 @@ createConnectionWithSocket(int sock, Bool closeOnRelease) /*FOLD00*/ memset(cPtr, 0, sizeof(WMConnection)); cPtr->sock = sock; - cPtr->sendTimeout.timeout = DEF_TIMEOUT; + cPtr->openTimeout.timeout = OpenTimeout; + cPtr->openTimeout.handler = NULL; + cPtr->sendTimeout.timeout = DefaultTimeout; cPtr->sendTimeout.handler = NULL; cPtr->closeOnRelease = closeOnRelease; cPtr->outputQueue = WMCreateBag(16); cPtr->state = WCNotConnected; + cPtr->timeoutState = WCTNone; /* ignore dead pipe */ if (!SigInitialized) { @@ -515,7 +556,6 @@ WMConnection* WMCreateConnectionToAddressAndNotify(char *host, char *service, char *protocol) /*FOLD00*/ { WMConnection *cPtr; - /*TimeoutData *tPtr;*/ struct sockaddr_in *socketaddr; int sock; Bool isNonBlocking; @@ -558,12 +598,12 @@ WMCreateConnectionToAddressAndNotify(char *host, char *service, char *protocol) cPtr->state = WCInProgress; cPtr->isNonBlocking = isNonBlocking; - /*tPtr = &cPtr->sendTimeout; - tPtr->handler = WMAddTimerHandler(tPtr->timeout*1000, connectTimeout, cPtr); - */ cPtr->handler.write = WMAddInputHandler(cPtr->sock, WIWriteMask, inputHandler, cPtr); + cPtr->openTimeout.handler = + WMAddTimerHandler(cPtr->openTimeout.timeout*1000, openTimeout, cPtr); + setConnectionAddress(cPtr, socketaddr); return cPtr; @@ -579,12 +619,15 @@ removeAllHandlers(WMConnection *cPtr) /*FOLD00*/ WMDeleteInputHandler(cPtr->handler.write); if (cPtr->handler.exception) WMDeleteInputHandler(cPtr->handler.exception); + if (cPtr->openTimeout.handler) + WMDeleteTimerHandler(cPtr->openTimeout.handler); if (cPtr->sendTimeout.handler) WMDeleteTimerHandler(cPtr->sendTimeout.handler); cPtr->handler.read = NULL; cPtr->handler.write = NULL; cPtr->handler.exception = NULL; + cPtr->openTimeout.handler = NULL; cPtr->sendTimeout.handler = NULL; } @@ -697,6 +740,13 @@ WMGetConnectionState(WMConnection *cPtr) /*FOLD00*/ } +WMConnectionTimeoutState +WMGetConnectionTimeoutState(WMConnection *cPtr) +{ + return cPtr->timeoutState; +} + + Bool WMEnqueueConnectionData(WMConnection *cPtr, WMData *data) /*FOLD00*/ { @@ -934,12 +984,35 @@ WMSetConnectionFlags(WMConnection *cPtr, unsigned int flags) /*FOLD00*/ void -WMSetConnectionSendTimeout(WMConnection *cPtr, unsigned int timeout) /*FOLD00*/ +WMSetConnectionDefaultTimeout(unsigned int timeout) { - if (timeout == 0) - timeout = DEF_TIMEOUT; + if (timeout == 0) { + DefaultTimeout = DEF_TIMEOUT; + } else { + DefaultTimeout = timeout; + } +} + - cPtr->sendTimeout.timeout = timeout; +void +WMSetConnectionOpenTimeout(unsigned int timeout) +{ + if (timeout == 0) { + OpenTimeout = DefaultTimeout; + } else { + OpenTimeout = timeout; + } +} + + +void +WMSetConnectionSendTimeout(WMConnection *cPtr, unsigned int timeout) /*FOLD00*/ +{ + if (timeout == 0) { + cPtr->sendTimeout.timeout = DefaultTimeout; + } else { + cPtr->sendTimeout.timeout = timeout; + } } diff --git a/WINGs/hashtable.c b/WINGs/hashtable.c index 239b518a..6eedfd84 100644 --- a/WINGs/hashtable.c +++ b/WINGs/hashtable.c @@ -392,7 +392,7 @@ const WMHashTableCallbacks WMStringHashCallbacks = { (hashFunc)hashString, (isEqualFunc)compareStrings, (retainFunc)wstrdup, - (releaseFunc)free + (releaseFunc)wfree }; -- 2.11.4.GIT