bool dequeue( msg_type & msg, boost::xtime const& xt) { typename boost::mutex::scoped_lock lock( mtx_); if ( active_ == false && empty_() ) return false; not_empty_cond_.timed_wait( lock, xt, boost::bind( & Queue< T, Q >::consumers_activate_, this) ); if ( empty_() ) msg.reset(); else dequeue_( msg); if ( active_ == true && queue_.size() <= low_water_mark_) not_full_cond_.notify_one(); return msg ? true : false; }
bool enqueue( msg_type const& msg, boost::xtime const& xt) { typename boost::mutex::scoped_lock lock( mtx_); if ( active_ == false) return false; not_full_cond_.timed_wait( lock, xt, boost::bind( & Queue< T, Q >::suppliers_activate_, this) ); if ( active_ != false) { enqueue_( msg); not_empty_cond_.notify_one(); return true; } else return false; }
void *SysQNode::Receive (int *pLen, bool Blocking) { boost::mutex::scoped_lock lock (m_EventMutex); assert (m_Sanity == 0xEDFEEFBE) ; if (m_Sanity != 0xEDFEEFBE) throw vfeInvalidDataError("Invalid sanity field in SysQNode::Receive"); if (m_Count == 0) { if (Blocking == false) return (NULL); // TODO: have a shorter wait but loop, and check for system shutdown // TODO FIXME - boost::xtime has been deprecated since boost 1.34. boost::xtime t; boost::xtime_get (&t, POV_TIME_UTC); t.nsec += 50000000 ; m_Event.timed_wait (lock, t); if (m_Count == 0) return (NULL) ; } DataNode *dNode = m_First ; if (dNode == NULL) throw vfeInvalidDataError("NULL data node in SysQNode::Receive"); void *dPtr = dNode->Data ; *pLen = dNode->Len ; if (dNode == m_Last) m_Last = NULL ; m_First = dNode->Next ; m_Count-- ; assert (m_Count != 0 || (m_First == NULL && m_Last == NULL)) ; POVMS_Sys_Free (dNode) ; return (dPtr) ; }
/// Entry point for the asynchronous monitor thread void run() { bool run = true; typedef std::pair< callback_t , std::pair< file_action, std::string> > notification; std::vector< notification> notifications; for (;;) { { // Lock and check m_run; if it was set to false, we must return ASAP boost::mutex::scoped_lock lock(m_run_mutex); run = m_run; if (!run) return; // We release the lock, block the thread until one second m_run_cond.timed_wait(lock, moost::thread::xtime_util::add_ms(moost::thread::xtime_util::now(), m_sleep_ms)); } // If we are not running (e.g. when the destructor woke us up), return if (!run) return; // Clear the notifications vector where we will collect the events // that will be fired notifications.clear(); { // Lock m_file_mutex while we are working on m_file_callback boost::mutex::scoped_lock lock(m_file_mutex); for (std::map<std::string, callback_t>::iterator it = m_file_callback.begin(); it != m_file_callback.end(); ++it) { boost::filesystem::path p(it->first); // Does the path exist? std::time_t lw = last_write_time(p); if (lw != 0) { // Check its last modification time and compare it with what we had earlier std::map< std::string, std::pair<time_t, time_t> >::iterator it_mod = m_file_modified.find(it->first); if (it_mod == m_file_modified.end()) { // We haven't seen this file so far, so insert it into the // map and add a creation event that will be fired m_file_modified[it->first] = std::make_pair(lw, lw); notifications.push_back(std::make_pair(it->second, std::make_pair(CREATED, it->first))); } else { // only case we consider a real modification: prev prev mod != prev mod, // but this mod == prev mod // the idea is that we want to capture a write to a file, // but only notify when the write is finished /** * \todo This could cause problems with frequent writing. * We should really use boost.interprocess file locking * instead (when we get 1.36 everywhere) */ if (lw == it_mod->second.second && it_mod->second.first != it_mod->second.second) notifications.push_back(std::make_pair(it->second, std::make_pair(CHANGED, it->first))); it_mod->second.first = it_mod->second.second; it_mod->second.second = lw; } } else { // The path does not exist. Did we have it before? If so, fire // a deletion event. std::map< std::string, std::pair<time_t, time_t> >::iterator it_mod = m_file_modified.find(it->first); if (it_mod != m_file_modified.end()) { m_file_modified.erase(it_mod); notifications.push_back(std::make_pair(it->second, std::make_pair(DELETED, it->first))); } } } } // okay! we've released our lock on m_file_callback and m_file_modified // so it's time to send off our notifications for (std::vector<notification>::iterator it = notifications.begin(); it != notifications.end(); ++it) { try { it->first(it->second.first, it->second.second); } catch (...) { // \todo can we do better here than silently ignoring the exception? } } } }
inline bool boost_threaded_monitor::timed_wait(unsigned int sec, unsigned int nanos) { boost::xtime xtm = { sec, nanos }; return cond_.timed_wait(lock_, xtm); }