コード例 #1
0
ファイル: queue.c プロジェクト: vmware/lightwave
DWORD
VmDirQueueDequeue(
    BOOL        bInLock,
    PVDIR_QUEUE pQueue,
    int64_t     iTimeoutMs,
    PVOID*      ppElement
    )
{
    DWORD dwError = 0;
    PVDIR_QUEUE_NODE pTemp= NULL;

    if (!pQueue || !ppElement)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, ERROR_INVALID_PARAMETER);
    }

    VMDIR_LOCK_MUTEX(bInLock, pQueue->pMutex);

    if (!pQueue->pHead)
    {
        if (iTimeoutMs < 0) // Blocking
        {
            while (!pQueue->pHead)
            {
                dwError = VmDirConditionWait(pQueue->pCond, pQueue->pMutex);
                BAIL_ON_VMDIR_ERROR(dwError);
            }
        }
        else if (iTimeoutMs > 0) // Waiting
        {
            VmDirConditionTimedWait(pQueue->pCond, pQueue->pMutex, iTimeoutMs);
            if (!pQueue->pHead)
            {
                dwError = VMDIR_ERROR_QUEUE_EMPTY;
            }
        }
        else // Non Blocking
        {
            dwError = VMDIR_ERROR_QUEUE_EMPTY;
        }
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    pQueue->iSize--;
    pTemp = pQueue->pHead;
    pQueue->pHead = pQueue->pHead->pNext;
    *ppElement = pTemp->pElement;
    VMDIR_SAFE_FREE_MEMORY(pTemp);

cleanup:
    VMDIR_UNLOCK_MUTEX(bInLock, pQueue->pMutex);
    return dwError;

error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError);
    goto cleanup;
}
コード例 #2
0
ファイル: connection.c プロジェクト: divyamehta/lightwave
static
DWORD
vmdirConnAccept(
    Sockbuf_IO*         pSockbuf_IO,
    DWORD               dwPort,
    BOOLEAN             bIsLdaps
    )
{
    ber_socket_t         newsockfd = -1;
    int                  retVal = LDAP_SUCCESS;
    ber_socket_t         ip4_fd = -1;
    ber_socket_t         ip6_fd = -1;
    ber_socket_t         max_fd = -1;
    VMDIR_THREAD         threadId;
    BOOLEAN              bInLock = FALSE;
    int                  iLocalLogMask = 0;
    PVDIR_CONNECTION_CTX pConnCtx = NULL;
    fd_set               event_fd_set;
    fd_set               poll_fd_set;
    struct timeval       timeout = {0};

    // Wait for ***1st*** replication cycle to be over.
    if (gVmdirServerGlobals.serverId == 0) // instance has not been initialized
    {
        VMDIR_LOG_WARNING( VMDIR_LOG_MASK_ALL, "Connection accept thread: Have NOT yet started listening on LDAP port (%u),"
                  " waiting for the 1st replication cycle to be over.", dwPort);

        VMDIR_LOCK_MUTEX(bInLock, gVmdirGlobals.replCycleDoneMutex);
        // wait till 1st replication cycle is over
        if (VmDirConditionWait( gVmdirGlobals.replCycleDoneCondition, gVmdirGlobals.replCycleDoneMutex ) != 0)
        {
            VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "Connection accept thread: VmDirConditionWait failed." );
            retVal = LDAP_OPERATIONS_ERROR;
            goto cleanup;
        }
        // also wake up the other (normal LDAP port/SSL LDAP port listner) LDAP connection accept thread,
        // waiting on 1st replication cycle to be over
        // BUGBUG Does not handle spurious wake up
        VmDirConditionSignal(gVmdirGlobals.replCycleDoneCondition);
        VMDIR_UNLOCK_MUTEX(bInLock, gVmdirGlobals.replCycleDoneMutex);

        if (VmDirdState() == VMDIRD_STATE_SHUTDOWN) // Asked to shutdown before we started accepting
        {
            goto cleanup;
        }

        VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Connection accept thread: listening on LDAP port (%u).", dwPort);
    }

    iLocalLogMask = VmDirLogGetMask();
    ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &iLocalLogMask);

    SetupLdapPort(dwPort, &ip4_fd, &ip6_fd);
    if (ip4_fd < 0 && ip6_fd < 0)
    {
        VmDirSleep(1000);
        goto cleanup;
    }

    FD_ZERO(&event_fd_set);
    if (ip4_fd >= 0)
    {
        FD_SET (ip4_fd, &event_fd_set);
        if (ip4_fd > max_fd)
        {
            max_fd = ip4_fd;
        }
    }

    if (ip6_fd >= 0)
    {
        FD_SET (ip6_fd, &event_fd_set);
        if (ip6_fd > max_fd)
        {
            max_fd = ip6_fd;
        }
    }

    retVal = VmDirSyncCounterIncrement(gVmdirGlobals.pPortListenSyncCounter);
    if (retVal != 0 )
    {
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s: VmDirSyncCounterIncrement(gVmdirGlobals.pPortListenSyncCounter) returned error", __func__);
        BAIL_ON_VMDIR_ERROR(retVal);
    }

    while (TRUE)
    {
        if (VmDirdState() == VMDIRD_STATE_SHUTDOWN)
        {
            goto cleanup;
        }

        poll_fd_set = event_fd_set;
        timeout.tv_sec = 3;
        timeout.tv_usec = 0;
        retVal = select ((int)max_fd+1, &poll_fd_set, NULL, NULL, &timeout);
        if (retVal < 0 )
        {
#ifdef _WIN32
            errno = WSAGetLastError();
#endif
            VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s: select() (port %d) call failed: %d.", __func__, dwPort, errno);
            VmDirSleep( 1000 );
            continue;
        } else if (retVal == 0)
        {
            //VMDIR_LOG_INFO( LDAP_DEBUG_CONNS, "%s: select() timeout (port %d)", __func__, dwPort);
            continue;
        }

        if (ip4_fd >= 0 && FD_ISSET(ip4_fd, &poll_fd_set))
        {
            newsockfd = accept(ip4_fd, (struct sockaddr *) NULL, NULL);
        } else if (ip6_fd >= 0 && FD_ISSET(ip6_fd, &poll_fd_set))
        {
            newsockfd = accept(ip6_fd, (struct sockaddr *) NULL, NULL);
        } else
        {
            VMDIR_LOG_INFO( LDAP_DEBUG_CONNS, "%s: select() returned with no data (port %d), return: %d",
                            __func__, dwPort, retVal);
            continue;
        }

        if (newsockfd < 0)
        {
#ifdef _WIN32
            errno = WSAGetLastError();
#endif
            if (errno != EAGAIN && errno != EWOULDBLOCK )
            {
                VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s: accept() (port %d) failed with errno: %d.",
                                 __func__, dwPort, errno );
            }
            continue;
        }

        if ( _VmDirFlowCtrlThrEnter() == TRUE )
        {
            tcp_close(newsockfd);
            newsockfd = -1;
            VMDIR_LOG_WARNING( VMDIR_LOG_MASK_ALL, "Maxmimum number of concurrent LDAP threads reached. Blocking new connection" );

            continue;
        }

        retVal = VmDirAllocateMemory(
                sizeof(VDIR_CONNECTION_CTX),
                (PVOID*)&pConnCtx);
        BAIL_ON_VMDIR_ERROR(retVal);

        pConnCtx->sockFd  = newsockfd;
        newsockfd = -1;
        pConnCtx->pSockbuf_IO = pSockbuf_IO;

        retVal = VmDirCreateThread(&threadId, TRUE, ProcessAConnection, (PVOID)pConnCtx);
        if (retVal != 0)
        {
            VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s: VmDirCreateThread() (port) failed with errno: %d",
                             __func__, dwPort, errno );

            tcp_close(pConnCtx->sockFd);
            _VmDirFlowCtrlThrExit();
            VMDIR_SAFE_FREE_MEMORY(pConnCtx);
            continue;
        }
        else
        {
            pConnCtx = NULL; //thread take ownership on pConnCtx
            VmDirFreeVmDirThread(&threadId);
        }
    }

cleanup:

    VMDIR_UNLOCK_MUTEX(bInLock, gVmdirGlobals.replCycleDoneMutex);

    if (ip4_fd >= 0)
    {
        tcp_close(ip4_fd);
    }
    if (ip6_fd >= 0)
    {
        tcp_close(ip6_fd);
    }
    if (newsockfd >= 0)
    {
        tcp_close(newsockfd);
    }
#ifndef _WIN32
    raise(SIGTERM);
#endif

    VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "%s: Connection accept thread: stop (port %d)", __func__, dwPort);

    return retVal;

error:
    goto cleanup;
}
コード例 #3
0
DWORD
VmDirIndexingThreadFun(
    PVOID   pArg
    )
{
    DWORD   dwError = 0;
    BOOLEAN bInLock = FALSE;
    BOOLEAN bResume = FALSE;
    VDIR_SERVER_STATE   vmdirState = VMDIRD_STATE_UNDEFINED;
    PVDIR_INDEXING_TASK pTask = NULL;

    VmDirDropThreadPriority(DEFAULT_THREAD_PRIORITY_DELTA);

resume:
    while (1)
    {
        vmdirState = VmDirdState();
        if (vmdirState == VMDIRD_STATE_SHUTDOWN)
        {
            break;
        }
        else if (vmdirState != VMDIRD_STATE_NORMAL)
        {
            VmDirSleep(1000);
            continue;
        }

        VMDIR_LOCK_MUTEX(bInLock, gVdirIndexGlobals.mutex);

        if (!bResume)
        {
            PVDIR_INDEX_UPD pIndexUpd = gVdirIndexGlobals.pIndexUpd;

            // record current progress
            dwError = VmDirIndexingTaskRecordProgress(pTask, pIndexUpd);
            BAIL_ON_VMDIR_ERROR(dwError);

            // apply index updates
            dwError = VmDirIndexUpdApply(pIndexUpd);
            BAIL_ON_VMDIR_ERROR(dwError);

            VmDirIndexUpdFree(pIndexUpd);
            gVdirIndexGlobals.pIndexUpd = NULL;

            // compute new task
            VmDirFreeIndexingTask(pTask);
            dwError = VmDirIndexingTaskCompute(&pTask);
            BAIL_ON_VMDIR_ERROR(dwError);
        }

        if (VmDirIndexingTaskIsNoop(pTask))
        {
            dwError = VmDirConditionWait(
                    gVdirIndexGlobals.cond,
                    gVdirIndexGlobals.mutex);
            BAIL_ON_VMDIR_ERROR(dwError);

            continue;
        }

        VMDIR_UNLOCK_MUTEX(bInLock, gVdirIndexGlobals.mutex);

        dwError = VmDirIndexingTaskPopulateIndices(pTask);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirIndexingTaskValidateScopes(pTask);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirIndexingTaskDeleteIndices(pTask);
        BAIL_ON_VMDIR_ERROR(dwError);
        bResume = FALSE;
    }

cleanup:
    VMDIR_UNLOCK_MUTEX(bInLock, gVdirIndexGlobals.mutex);
    VmDirFreeIndexingTask(pTask);
    return dwError;

error:
    if (dwError == ERROR_INVALID_STATE)
    {
        bResume = TRUE;
        goto resume;
    }
    else
    {
        VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
                "%s failed, error (%d)", __FUNCTION__, dwError );
    }
    goto cleanup;
}
コード例 #4
0
ファイル: indexingthr.c プロジェクト: saberlilydian/lightwave
/*
 * This thread waits on gVdirAttrIndexGlobals.condition and spawns worker thread
 * to perform indexing in the back ground.
 */
static
DWORD
vdirIndexingThrFun(
    PVOID   pArg
)
{
    DWORD   dwError = 0;
    BOOLEAN bInLock = FALSE;
    PVDIR_CFG_ATTR_INDEX_DESC*  ppIndexDesc = NULL;
    PVDIR_THREAD_INFO           pThrInfo = (PVDIR_THREAD_INFO)pArg;

    while (1)
    {
        DWORD   dwCnt = 0;
        DWORD   dwSize = 0;
        VMDIR_THREAD  tid = {0};
        PVDIR_ATTR_INDEX_INSTANCE pCache = NULL;

        memset(&tid, 0, sizeof(tid));

        // wait till new indices are created
        VMDIR_LOCK_MUTEX(bInLock, gVdirAttrIndexGlobals.mutex);

        dwError = VmDirConditionWait(
                      pThrInfo->conditionUsed,
                      pThrInfo->mutexUsed);
        BAIL_ON_VMDIR_ERROR(dwError);

        // get new cache we want to enable
        pCache = gVdirAttrIndexGlobals.pNewCache;

        VMDIR_UNLOCK_MUTEX(bInLock, gVdirAttrIndexGlobals.mutex);

        if (VmDirdState() == VMDIRD_STATE_SHUTDOWN)
        {
            break;
        }

        if (!pCache)
        {
            continue;
        }

        // get number of indices in building status
        for (dwCnt = 0, dwSize = 0; dwCnt < pCache->usNumIndex; dwCnt++)
        {
            if (pCache->pSortName[dwCnt].status == VDIR_CFG_ATTR_INDEX_BUILDING)
            {
                dwSize++;
            }
        }

        if (dwSize == 0)
        {
            continue;
        }

        dwError  = VmDirAllocateMemory(
                       sizeof(PVDIR_CFG_ATTR_INDEX_DESC) * (dwSize + 1),  // +1 for NULL ending
                       (PVOID)&ppIndexDesc);
        BAIL_ON_VMDIR_ERROR(dwError);

        // fill ppIndexDesc with building index
        // NOTE, ppIndexDesc does NOT own them; pCache does.
        for (dwCnt = 0, dwSize = 0; dwCnt < pCache->usNumIndex; dwCnt++)
        {
            if (pCache->pSortName[dwCnt].status == VDIR_CFG_ATTR_INDEX_BUILDING)
            {
                ppIndexDesc[dwSize] = &pCache->pSortName[dwCnt];
                dwSize++;
            }
        }

        // TODO, detach thr now, need to join to safely finish bdb io...
        dwError = VmDirCreateThread(
                      &tid,
                      TRUE,
                      vdirIndexingWorkerThrFun,
                      (PVOID)ppIndexDesc);
        BAIL_ON_VMDIR_ERROR(dwError);
        // worker takes over ppIndexDesc.
        ppIndexDesc = NULL;

        VmDirFreeVmDirThread(&tid);
    }

cleanup:

    VMDIR_UNLOCK_MUTEX(bInLock, gVdirAttrIndexGlobals.mutex);

    // TODO: should be dwError?
    return 0;

error:

    VMDIR_SAFE_FREE_MEMORY(ppIndexDesc);

    //TODO, should we stop vmdird?

    VmDirLog( LDAP_DEBUG_ANY, "VmdirIndexingThr: error stop" );

    goto cleanup;
}