//-------------------------------------------------------------------------------------------------- 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."); }
//-------------------------------------------------------------------------------------------------- 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; }
//-------------------------------------------------------------------------------------------------- ni_IteratorRef_t ni_InternalRefFromExternalRef ( tu_UserRef_t userRef, ///< We're getting an iterator for this user. le_cfg_IteratorRef_t externalRef ///< The reference we're to look up. ) //-------------------------------------------------------------------------------------------------- { LE_ASSERT(externalRef != NULL); LE_ASSERT(userRef != NULL); ni_IteratorRef_t iteratorRef = le_ref_Lookup(IteratorRefMap, externalRef); if ( (iteratorRef == NULL) || (tu_GetUserId(userRef) != tu_GetUserId(iteratorRef->userRef))) { LE_ERROR("Iterator reference <%p> not found.", iteratorRef); return NULL; } return iteratorRef; }
//-------------------------------------------------------------------------------------------------- void tu_SessionDisconnected ( le_msg_SessionRef_t sessionRef ///< [IN] The session just disconnected. ) //-------------------------------------------------------------------------------------------------- { tu_UserRef_t userRef = GetUserInfo(sessionRef, NULL); uid_t userId = tu_GetUserId(userRef); // If this isn't the root user, de-ref the user info. (We don't free the root user.) if (userId != 0) { le_mem_Release(userRef); } }
//-------------------------------------------------------------------------------------------------- void tu_SessionConnected ( le_msg_SessionRef_t sessionRef ///< [IN] The session just connected. ) //-------------------------------------------------------------------------------------------------- { bool wasCreated; tu_UserRef_t userRef = GetUserInfo(sessionRef, &wasCreated); if ( (wasCreated == false) && (tu_GetUserId(userRef) != 0)) { le_mem_AddRef(userRef); } }
//-------------------------------------------------------------------------------------------------- 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); }
//-------------------------------------------------------------------------------------------------- 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; }