int reSvrSleep (rsComm_t *rsComm) { int status; rodsServerHost_t *rodsServerHost = NULL; if ((status = disconnRcatHost (rsComm, MASTER_RCAT, rsComm->myEnv.rodsZone)) == LOCAL_HOST) { #ifdef RODS_CAT #ifndef ORA_ICAT /* For Oracle, we don't disconnect. This is to avoid a memory leak in the OCI library */ disconnectRcat (rsComm); if (status < 0) { rodsLog (LOG_ERROR, "reSvrSleep: disconnectRcat error. status = %d", status); } #endif #endif } rodsSleep (RE_SERVER_SLEEP_TIME, 0); if ((status = getAndConnRcatHost (rsComm, MASTER_RCAT, rsComm->myEnv.rodsZone, &rodsServerHost)) == LOCAL_HOST) { #ifdef RODS_CAT status = connectRcat (rsComm); if (status < 0) { rodsLog (LOG_ERROR, "reSvrSleep: connectRcat error. status = %d", status); } #endif } return (status); }
/** * \fn msiSleep(msParam_t* secPtr, msParam_t* microsecPtr, ruleExecInfo_t *rei) * * \brief Sleep for some amount of time * * \module core * * \since pre-2.1 * * \author Arcot Rajasekar * \date 2008-05 * * \usage See clients/icommands/test/rules3.0/ * * \param[in] secPtr - secPtr is a msParam of type STR_MS_T which is seconds * \param[in] microsecPtr - microsecPrt is a msParam of type STR_MS_T which is microseconds * \param[in,out] rei - The RuleExecInfo structure that is automatically * handled by the rule engine. The user does not include rei as a * parameter in the rule invocation. * * \DolVarDependence none * \DolVarModified none * \iCatAttrDependence none * \iCatAttrModified none * \sideeffect none * * \return integer * \retval 0 on success * \pre none * \post none * \sa none **/ int msiSleep( msParam_t* secPtr, msParam_t* microsecPtr, ruleExecInfo_t *rei ) { int sec, microsec; sec = atoi( ( char * ) secPtr->inOutStruct ); microsec = atoi( ( char * ) microsecPtr->inOutStruct ); rodsSleep( sec, microsec ); return( 0 ); }
void connManager() { time_t curTime; iFuseConn_t *tmpIFuseConn; ListNode *node; List *TimeOutList = newListNoRegion(); while ( 1 ) { curTime = time( NULL ); /* exceed high water mark for number of connection ? */ if ( listSize( ConnectedConn ) > HIGH_NUM_CONN ) { LOCK_STRUCT( *ConnectedConn ); int disconnTarget = _listSize( ConnectedConn ) - HIGH_NUM_CONN; node = ConnectedConn->list->head; while ( node != NULL ) { tmpIFuseConn = ( iFuseConn_t * ) node->value; if ( tmpIFuseConn->inuseCnt == 0 && tmpIFuseConn->pendingCnt == 0 && curTime - tmpIFuseConn->actTime > IFUSE_CONN_TIMEOUT ) { listAppendNoRegion( TimeOutList, tmpIFuseConn ); } node = node->next; } UNLOCK_STRUCT( *ConnectedConn ); node = TimeOutList->head; int disconned = 0; while ( node != NULL && disconned < disconnTarget ) { tmpIFuseConn = ( iFuseConn_t * ) node->value; LOCK_STRUCT( *tmpIFuseConn ); if ( tmpIFuseConn->inuseCnt == 0 && tmpIFuseConn->pendingCnt == 0 && curTime - tmpIFuseConn->actTime > IFUSE_CONN_TIMEOUT ) { removeFromConcurrentList2( FreeConn, tmpIFuseConn ); removeFromConcurrentList2( ConnectedConn, tmpIFuseConn ); if ( tmpIFuseConn->status == 0 ) { /* no struct is referring to it, we can unlock it and free it */ UNLOCK_STRUCT( *tmpIFuseConn ); /* rodsLog(LOG_ERROR, "[FREE IFUSE CONN] %s:%d %p", __FILE__, __LINE__, tmpIFuseConn); */ _freeIFuseConn( tmpIFuseConn ); } else { /* set to timed out */ _ifuseDisconnect( tmpIFuseConn ); UNLOCK_STRUCT( *tmpIFuseConn ); } disconned ++; } else { UNLOCK_STRUCT( *tmpIFuseConn ); } node = node->next; } clearListNoRegion( TimeOutList ); } while ( listSize( ConnectedConn ) <= MAX_NUM_CONN || listSize( FreeConn ) != 0 ) { /* signal one in the wait queue */ connReqWait_t *myConnReqWait = ( connReqWait_t * ) removeFirstElementOfConcurrentList( ConnReqWaitQue ); /* if there is no conn req left, exit loop */ if ( myConnReqWait == NULL ) { break; } myConnReqWait->state = 1; notifyTimeoutWait( &myConnReqWait->mutex, &myConnReqWait->cond ); } #if 0 rodsSleep( CONN_MANAGER_SLEEP_TIME, 0 ); #else timeoutWait( &ConnManagerLock, &ConnManagerCond, CONN_MANAGER_SLEEP_TIME ); #endif } deleteListNoRegion( TimeOutList ); }
int connectToRhostWithTout( int sock, struct sockaddr *sin ) { int timeoutCnt = 0; #ifdef _WIN32 // A Windows console app has very limited timeout functionality. // An pseudo timeout is implemented. int status = 0; while ( ( timeoutCnt < MAX_CONN_RETRY_CNT ) && ( !win_connect_timeout ) ) { if ( ( status = connect( sock, sin, sizeof( struct sockaddr ) ) ) < 0 ) { timeoutCnt ++; rodsSleep( 0, 200000 ); } else { break; } } if ( status != 0 ) { return USER_SOCK_CONNECT_TIMEDOUT; } return 0; #else /* redo the timeout using select */ /* Set non-blocking */ long arg = fcntl( sock, F_GETFL, NULL ); if ( arg < 0 ) { rodsLog( LOG_ERROR, "connectToRhostWithTout: fcntl F_GETFL error, errno = %d", errno ); return USER_SOCK_CONNECT_ERR; } arg |= O_NONBLOCK; if ( fcntl( sock, F_SETFL, arg ) < 0 ) { rodsLog( LOG_ERROR, "connectToRhostWithTout: fcntl F_SETFL error, errno = %d", errno ); return USER_SOCK_CONNECT_ERR; } int status = 0; while ( timeoutCnt < MAX_CONN_RETRY_CNT ) { status = connect( sock, sin, sizeof( struct sockaddr ) ); if ( status >= 0 ) { break; } if ( errno == EISCONN ) { /* already connected. seen this error on AIX */ status = 0; break; } if ( errno == EINPROGRESS || errno == EINTR ) { struct timeval tv; tv.tv_sec = CONNECT_TIMEOUT_TIME; tv.tv_usec = 0; fd_set myset; FD_ZERO( &myset ); FD_SET( sock, &myset ); status = select( sock + 1, NULL, &myset, NULL, &tv ); if ( status < 0 ) { if ( errno != EINTR ) { rodsLog( LOG_NOTICE, "connectToRhostWithTout: connect error, errno = %d", errno ); timeoutCnt++; } continue; } else if ( status > 0 ) { int myval; #if defined(aix_platform) socklen_t mylen = sizeof( int ); #else uint mylen = sizeof( int ); #endif if ( getsockopt( sock, SOL_SOCKET, SO_ERROR, ( void* )( &myval ), &mylen ) < 0 ) { rodsLog( LOG_ERROR, "connectToRhostWithTout: getsockopt error, errno = %d", errno ); return USER_SOCK_CONNECT_ERR - errno; } /* Check the returned value */ if ( myval ) { rodsLog( LOG_NOTICE, "connectToRhostWithTout: connect error, errno = %d", myval ); timeoutCnt++; status = USER_SOCK_CONNECT_ERR - myval; continue; } else { break; } } else { /* timed out */ status = USER_SOCK_CONNECT_TIMEDOUT; break; } } else { rodsLog( LOG_NOTICE, "connectToRhostWithTout: connect error, errno = %d", errno ); timeoutCnt++; status = USER_SOCK_CONNECT_ERR - errno; continue; } } if ( status < 0 ) { if ( status == -1 ) { return USER_SOCK_CONNECT_ERR; } else { return status; } } /* Set to blocking again */ if ( ( arg = fcntl( sock, F_GETFL, NULL ) ) < 0 ) { rodsLog( LOG_ERROR, "connectToRhostWithTout: fcntl F_GETFL error, errno = %d", errno ); return USER_SOCK_CONNECT_ERR; } arg &= ( ~O_NONBLOCK ); if ( fcntl( sock, F_SETFL, arg ) < 0 ) { rodsLog( LOG_ERROR, "connectToRhostWithTout: fcntl F_SETFL error, errno = %d", errno ); return USER_SOCK_CONNECT_ERR; } return status; #endif }
void cliReconnManager( rcComm_t *conn ) { struct sockaddr_in remoteAddr; struct hostent *myHostent; reconnMsg_t reconnMsg; reconnMsg_t *reconnMsgOut = NULL; if ( conn == NULL || conn->svrVersion == NULL || conn->svrVersion->reconnPort <= 0 ) { return; } conn->reconnTime = time( 0 ) + RECONN_TIMEOUT_TIME; while ( !conn->exit_flg ) { /* JMC */ time_t curTime = time( 0 ); if ( curTime < conn->reconnTime ) { rodsSleep( conn->reconnTime - curTime, 0 ); } boost::unique_lock<boost::mutex> boost_lock; try { boost_lock = boost::unique_lock<boost::mutex>( *conn->thread_ctx->lock ); } catch ( const boost::lock_error& ) { rodsLog( LOG_ERROR, "lock_error on unique_lock" ); return; } /* need to check clientState */ while ( conn->clientState != PROCESSING_STATE ) { /* have to wait until the client stop sending */ conn->reconnThrState = CONN_WAIT_STATE; rodsLog( LOG_DEBUG, "cliReconnManager: clientState = %d", conn->clientState ); printf( "cliReconnManager: clientState = %d\n", conn->clientState ); fflush( stdout ); conn->thread_ctx->cond->wait( boost_lock ); } rodsLog( LOG_DEBUG, "cliReconnManager: Reconnecting clientState = %d", conn->clientState ); printf( "cliReconnManager: Reconnecting clientState = %d\n", conn->clientState ); fflush( stdout ); conn->reconnThrState = PROCESSING_STATE; /* connect to server's reconn thread */ myHostent = gethostbyname( conn->svrVersion->reconnAddr ); if ( myHostent == NULL || myHostent->h_addrtype != AF_INET ) { rodsLog( LOG_ERROR, "cliReconnManager: unknown hostname: %s", conn->svrVersion->reconnAddr ); return; } memcpy( &remoteAddr.sin_addr, myHostent->h_addr, myHostent->h_length ); remoteAddr.sin_family = AF_INET; remoteAddr.sin_port = htons( ( unsigned short ) conn->svrVersion->reconnPort ); conn->reconnectedSock = connectToRhostWithRaddr( &remoteAddr, conn->windowSize, 0 ); if ( conn->reconnectedSock < 0 ) { conn->thread_ctx->cond->notify_all(); boost_lock.unlock(); rodsLog( LOG_ERROR, "cliReconnManager: connect to host %s failed, status = %d", conn->svrVersion->reconnAddr, conn->reconnectedSock ); printf( "cliReconnManager: connect to host %s failed, status = %d\n", conn->svrVersion->reconnAddr, conn->reconnectedSock ); fflush( stdout ); rodsSleep( RECONNECT_SLEEP_TIME, 0 ); continue; } bzero( &reconnMsg, sizeof( reconnMsg_t ) ); reconnMsg.procState = conn->clientState; reconnMsg.cookie = conn->svrVersion->cookie; // =-=-=-=-=-=-=- // create network object, need to override the socket // with the reconn socket. no way to infer this in the // factory for the client comm irods::network_object_ptr net_obj; irods::error ret = irods::network_factory( conn, net_obj ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); } net_obj->socket_handle( conn->reconnectedSock ); // repave w/ recon socket ret = sendReconnMsg( net_obj, &reconnMsg ); if ( !ret.ok() ) { close( conn->reconnectedSock ); conn->reconnectedSock = 0; conn->thread_ctx->cond->notify_all(); boost_lock.unlock(); rodsLog( LOG_ERROR, "cliReconnManager: sendReconnMsg to host %s failed, status = %d", conn->svrVersion->reconnAddr, ret.code() ); rodsSleep( RECONNECT_SLEEP_TIME, 0 ); continue; } ret = readReconMsg( net_obj, &reconnMsgOut ); if ( !ret.ok() ) { close( conn->reconnectedSock ); conn->reconnectedSock = 0; conn->thread_ctx->cond->notify_all(); boost_lock.unlock(); rodsLog( LOG_ERROR, "cliReconnManager: readReconMsg to host %s failed, status = %d", conn->svrVersion->reconnAddr, ret.code() ); rodsSleep( RECONNECT_SLEEP_TIME, 0 ); continue; } conn->agentState = reconnMsgOut->procState; free( reconnMsgOut ); reconnMsgOut = NULL; conn->reconnTime = time( 0 ) + RECONN_TIMEOUT_TIME; if ( conn->clientState == PROCESSING_STATE ) { rodsLog( LOG_DEBUG, "cliReconnManager: svrSwitchConnect. cliState = %d,agState=%d", conn->clientState, conn->agentState ); cliSwitchConnect( conn ); } else { rodsLog( LOG_DEBUG, "cliReconnManager: Not calling svrSwitchConnect, clientState = %d", conn->clientState ); } conn->thread_ctx->cond->notify_all(); boost_lock.unlock(); } }