//-------------------------------------------------------------------------------------------------- void le_fdMonitor_SetDeferrable ( le_fdMonitor_Ref_t monitorRef, ///< [in] Reference to the File Descriptor Monitor object. bool isDeferrable ///< [in] true (deferrable) or false (urgent). ) //-------------------------------------------------------------------------------------------------- { // Look up the File Descriptor Monitor object using the safe reference provided. // Note that the safe reference map is shared by all threads in the process, so it // must be protected using the mutex. The File Descriptor Monitor objects, on the other // hand, are only allowed to be accessed by the one thread that created them, so it is // safe to unlock the mutex after doing the safe reference lookup. LOCK FdMonitor_t* monitorPtr = le_ref_Lookup(FdMonitorRefMap, monitorRef); UNLOCK LE_FATAL_IF(monitorPtr == NULL, "File Descriptor Monitor %p doesn't exist!", monitorRef); LE_FATAL_IF(thread_GetEventRecPtr() != monitorPtr->threadRecPtr, "FD Monitor '%s' (fd %d) is owned by another thread.", monitorPtr->name, monitorPtr->fd); // Set/clear the EPOLLWAKEUP flag in the FD Monitor's epoll(7) flags set. if (isDeferrable) { monitorPtr->epollEvents &= ~EPOLLWAKEUP; } else { monitorPtr->epollEvents |= EPOLLWAKEUP; } UpdateEpollFd(monitorPtr); }
//-------------------------------------------------------------------------------------------------- void le_fdMonitor_Enable ( le_fdMonitor_Ref_t monitorRef, ///< [in] Reference to the File Descriptor Monitor object. short events ///< [in] Bit map of events. ) //-------------------------------------------------------------------------------------------------- { // Look up the File Descriptor Monitor object using the safe reference provided. // Note that the safe reference map is shared by all threads in the process, so it // must be protected using the mutex. The File Descriptor Monitor objects, on the other // hand, are only allowed to be accessed by the one thread that created them, so it is // safe to unlock the mutex after doing the safe reference lookup. LOCK FdMonitor_t* monitorPtr = le_ref_Lookup(FdMonitorRefMap, monitorRef); UNLOCK LE_FATAL_IF(monitorPtr == NULL, "File Descriptor Monitor %p doesn't exist!", monitorRef); LE_FATAL_IF(thread_GetEventRecPtr() != monitorPtr->threadRecPtr, "FD Monitor '%s' (fd %d) is owned by another thread.", monitorPtr->name, monitorPtr->fd); short filteredEvents = events & (POLLIN | POLLOUT | POLLPRI); if (filteredEvents != events) { char textBuff[64]; LE_WARN("Attempt to enable events that can't be disabled (%s).", GetPollEventsText(textBuff, sizeof(textBuff), events & ~filteredEvents)); } uint32_t epollEvents = PollToEPoll(filteredEvents); // If the fd doesn't support epoll, we assume it is always ready for read and write. // As long as EPOLLIN or EPOLLOUT (or both) is enabled for one of these fds, DispatchToHandler() // keeps re-queueing itself to the thread's event queue. But it will stop doing that if // EPOLLIN and EPOLLOUT are both disabled. So, here is where we get things going again when // EPOLLIN or EPOLLOUT is enabled outside DispatchToHandler() for that fd. if ( (monitorPtr->isAlwaysReady) && (epollEvents & (EPOLLIN | EPOLLOUT)) && ((monitorPtr->epollEvents & (EPOLLIN | EPOLLOUT)) == 0) ) { // Fetch the pointer to the FD Monitor from thread-specific data. // This will be NULL if we are not inside an FD Monitor handler. FdMonitor_t* handlerMonitorPtr = pthread_getspecific(FDMonitorPtrKey); // If no handler is running or some other fd's handler is running, if ((handlerMonitorPtr == NULL) || (handlerMonitorPtr->safeRef == monitorRef)) { // Queue up DispatchToHandler() for this fd. fdMon_Report(monitorRef, epollEvents & (EPOLLIN | EPOLLOUT)); } } // Bit-wise OR the newly enabled event flags into the FD Monitor's epoll(7) flags set. monitorPtr->epollEvents |= epollEvents; UpdateEpollFd(monitorPtr); }
//-------------------------------------------------------------------------------------------------- static void DisableFdMonitoring ( FdMonitor_t* monitorPtr, le_event_FdEventType_t eventType ) //-------------------------------------------------------------------------------------------------- { // Remove the epoll event flag from the flag set being monitored for this fd. // (Not possible for EPOLLERR or EPOLLHUP. They are always monitored, no matter what.) uint32_t epollEventFlag = ConvertToEPollFlag(eventType, monitorPtr->wakeUp); // Note: checks eventType. if ((epollEventFlag != EPOLLERR) && (epollEventFlag != EPOLLHUP)) { monitorPtr->epollEvents &= (~epollEventFlag); UpdateEpollFd(monitorPtr); } }
//-------------------------------------------------------------------------------------------------- static void EnableFdMonitoring ( FdMonitor_t* monitorPtr, le_event_FdEventType_t eventType ) //-------------------------------------------------------------------------------------------------- { // Add the epoll event flag to the flag set being monitored for this fd. // (Not necessary for EPOLLERR or EPOLLHUP. They are always monitored, no matter what.) uint32_t epollEventFlag = ConvertToEPollFlag(eventType, monitorPtr->wakeUp); // Note: checks eventType. if ((epollEventFlag != EPOLLERR) && (epollEventFlag != EPOLLHUP)) { monitorPtr->epollEvents |= epollEventFlag; UpdateEpollFd(monitorPtr); } }
//-------------------------------------------------------------------------------------------------- void le_fdMonitor_Disable ( le_fdMonitor_Ref_t monitorRef, ///< [in] Reference to the File Descriptor Monitor object. short events ///< [in] Bit map of events. ) //-------------------------------------------------------------------------------------------------- { // Look up the File Descriptor Monitor object using the safe reference provided. // Note that the safe reference map is shared by all threads in the process, so it // must be protected using the mutex. The File Descriptor Monitor objects, on the other // hand, are only allowed to be accessed by the one thread that created them, so it is // safe to unlock the mutex after doing the safe reference lookup. LOCK FdMonitor_t* monitorPtr = le_ref_Lookup(FdMonitorRefMap, monitorRef); UNLOCK LE_FATAL_IF(monitorPtr == NULL, "File Descriptor Monitor %p doesn't exist!", monitorRef); LE_FATAL_IF(thread_GetEventRecPtr() != monitorPtr->threadRecPtr, "FD Monitor '%s' (fd %d) is owned by another thread.", monitorPtr->name, monitorPtr->fd); short filteredEvents = events & (POLLIN | POLLOUT | POLLPRI); LE_WARN_IF(filteredEvents != events, "Only POLLIN, POLLOUT, and POLLPRI events can be disabled. (fd monitor '%s')", monitorPtr->name); // Convert the events from POLLxx events to EPOLLxx events. uint32_t epollEvents = PollToEPoll(filteredEvents); // Remove them from the FD Monitor's epoll(7) flags set. monitorPtr->epollEvents &= (~epollEvents); UpdateEpollFd(monitorPtr); }