예제 #1
0
//--------------------------------------------------------------------------------------------------
static void OnTransactionTimeout
(
    le_timer_Ref_t timerRef   ///< The timer that expired.
)
//--------------------------------------------------------------------------------------------------
{
    // Extract the iterator reference out of the timer object.  Then perform a sanity check to make
    // sure everything is going to plan.
    ni_IteratorRef_t iteratorRef = (ni_IteratorRef_t)le_timer_GetContextPtr(timerRef);
    LE_ASSERT(iteratorRef->timerRef == timerRef);

    // For clearer message reporting, figure out if this is a read or write transaction.
    char* iterTypePtr = "Read";

    if (ni_IsWriteable(iteratorRef))
    {
        iterTypePtr = "Write";
    }

    if (iteratorRef->isTerminated)
    {
        LE_DEBUG("Previously terminated iterator, <%p> timed out.", iteratorRef);
        return;
    }

    // Report the failure in the log, and close the client session.  Once the session is closed all
    // of that user's resources within the configTree will be naturally cleaned up.
    LE_EMERG("%s transaction <%p> timer expired, for user %s, <%d>.",
             iterTypePtr,
             iteratorRef->reference,
             tu_GetUserName(iteratorRef->userRef),
             tu_GetUserId(iteratorRef->userRef));

    tu_TerminateConfigClient(iteratorRef->sessionRef, "Transaction timeout.");
}
예제 #2
0
//--------------------------------------------------------------------------------------------------
ni_IteratorRef_t ni_CreateIterator
(
    le_msg_SessionRef_t sessionRef,  ///< The user session this request occured on.
    tu_UserRef_t userRef,            ///< Create the iterator for this user.
    tdb_TreeRef_t treeRef,           ///< The tree to create the iterator with.
    ni_IteratorType_t type,          ///< The type of iterator we are creating, read or write?
    const char* initialPathPtr       ///< The node to move to in the specified tree.
)
//--------------------------------------------------------------------------------------------------
{
    LE_ASSERT(sessionRef != NULL);
    LE_ASSERT(userRef != NULL);
    LE_ASSERT(treeRef != NULL);

    // Allocate the object and setup it's initial properties.
    ni_IteratorRef_t iteratorRef = le_mem_ForceAlloc(IteratorPoolRef);

    iteratorRef->sessionRef = sessionRef;
    iteratorRef->userRef = userRef;
    iteratorRef->treeRef = treeRef;
    iteratorRef->type = type;
    iteratorRef->reference = NULL;
    iteratorRef->isClosed = false;

    // If this is a write iterator, then shadow the tree instead of accessing it directly.
    if (iteratorRef->type == NI_WRITE)
    {
        iteratorRef->treeRef = tdb_ShadowTree(iteratorRef->treeRef);
    }

    // Get the root node of the requested tree, or if this is a write iterator...  Get the shadowed
    // root node of the tree.
    iteratorRef->currentNodeRef = tdb_GetRootNode(iteratorRef->treeRef);
    iteratorRef->pathIterRef = le_pathIter_CreateForUnix("/");

    LE_DEBUG("Created a new %s iterator object <%p> for user %u (%s) on tree %s.",
             TypeString(type),
             iteratorRef,
             tu_GetUserId(userRef),
             tu_GetUserName(userRef),
             tdb_GetTreeName(treeRef));

     // If we were given an initial path, go to it now.  Otherwise stay on the root node.
    if (initialPathPtr)
    {
        ni_GoToNode(iteratorRef, initialPathPtr);
    }

    // Update the tree so that it can keep track of this iterator.
    tdb_RegisterIterator(treeRef, iteratorRef);

    // All done.
    return iteratorRef;
}
예제 #3
0
//--------------------------------------------------------------------------------------------------
void tu_TerminateConfigAdminClient
(
    le_msg_SessionRef_t sessionRef,  ///< [IN] The session that needs to close.
    const char* killMessage          ///< [IN] The reason the session needs to close.
)
//--------------------------------------------------------------------------------------------------
{
    tu_UserRef_t userRef = GetUserInfo(sessionRef, NULL);

    LE_EMERG("A fatal error occured.  Killing admin sesssion <%p> for user %s, <%u>.  Reason: %s",
             sessionRef,
             tu_GetUserName(userRef),
             tu_GetUserId(userRef),
             killMessage);

    le_msg_CloseSession(sessionRef);
}
예제 #4
0
//--------------------------------------------------------------------------------------------------
ni_IteratorRef_t ni_CreateIterator
(
    le_msg_SessionRef_t sessionRef,  ///< [IN] The user session this request occured on.
    tu_UserRef_t userRef,            ///< [IN] Create the iterator for this user.
    tdb_TreeRef_t treeRef,           ///< [IN] The tree to create the iterator with.
    ni_IteratorType_t type,          ///< [IN] The type of iterator we are creating, read or write?
    const char* initialPathPtr       ///< [IN] The node to move to in the specified tree.
)
//--------------------------------------------------------------------------------------------------
{
    LE_ASSERT(treeRef != NULL);

    // Allocate the object and setup it's initial properties.
    ni_IteratorRef_t iteratorRef = le_mem_ForceAlloc(IteratorPoolRef);

    iteratorRef->creationTime = le_clk_GetRelativeTime();
    iteratorRef->sessionRef = sessionRef;
    iteratorRef->userRef = userRef;
    iteratorRef->treeRef = treeRef;
    iteratorRef->type = type;
    iteratorRef->reference = NULL;
    iteratorRef->isClosed = false;
    iteratorRef->isTerminated = false;

    // Setup the timeout timer for this transaction, if it's been configured.
    time_t configTimeout = ic_GetTransactionTimeout();

    if (configTimeout > 0)
    {
        le_clk_Time_t timeout = { configTimeout, 0 };
        iteratorRef->timerRef = le_timer_Create("Transaction Timer");

        LE_ASSERT(le_timer_SetInterval(iteratorRef->timerRef, timeout) == LE_OK);
        LE_ASSERT(le_timer_SetHandler(iteratorRef->timerRef, OnTransactionTimeout) == LE_OK);
        LE_ASSERT(le_timer_SetContextPtr(iteratorRef->timerRef, iteratorRef) == LE_OK);

        LE_ASSERT(le_timer_Start(iteratorRef->timerRef) == LE_OK);
    }
    else
    {
        iteratorRef->timerRef = NULL;
    }

    // If this is a write iterator, then shadow the tree instead of accessing it directly.
    if (iteratorRef->type == NI_WRITE)
    {
        iteratorRef->treeRef = tdb_ShadowTree(iteratorRef->treeRef);
    }

    // Get the root node of the requested tree, or if this is a write iterator...  Get the shadowed
    // root node of the tree.
    iteratorRef->currentNodeRef = tdb_GetRootNode(iteratorRef->treeRef);
    iteratorRef->pathIterRef = le_pathIter_CreateForUnix("/");


    LE_DEBUG("Created a new %s iterator object <%p> for user %u (%s) on tree %s.",
             TypeString(type),
             iteratorRef,
             tu_GetUserId(userRef),
             tu_GetUserName(userRef),
             tdb_GetTreeName(treeRef));

     // If we were given an initial path, go to it now.  Otherwise stay on the root node.
    if (initialPathPtr)
    {
        ni_GoToNode(iteratorRef, initialPathPtr);
    }

    // Update the tree so that it can keep track of this iterator.
    tdb_RegisterIterator(treeRef, iteratorRef);

    // All done.
    return iteratorRef;
}