예제 #1
0
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);
}
예제 #2
0
/**
 * \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 );
}
예제 #3
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 );
}
예제 #4
0
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
}
예제 #5
0
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();
    }
}