00001 /* 00002 wefts_subscription.h 00003 Subscribe + notify system implementation 00004 00005 $Id: wefts_subscription.h,v 1.9 2004/03/08 20:28:53 jonnymind Exp $ 00006 ---------------------------------------------- 00007 Begin : 2003-08-02 00:10 00008 Author : Giancarlo Niccolai 00009 00010 Last modified because: 00011 00012 */ 00013 00014 /************************************************************************** 00015 * This program is free software; you can redistribute it and/or modify * 00016 * it under the terms of the GNU Library General Public License as * 00017 * published by the Free Software Foundation; either version 2.1 of the * 00018 * License, or (at your option) any later version. * 00019 ***************************************************************************/ 00020 00021 #ifndef WT_SUBSCRIPTION_H 00022 #define WT_SUBSCRIPTION_H 00023 00024 #include <wefts_os.h> 00025 #include <wefts_thread.h> 00026 #include <wefts_cleanup.h> 00027 #include <wefts_fastcond.h> 00028 #include <wefts_referenced.h> 00029 #include <list> 00030 00031 namespace Wefts { 00032 00033 00122 class Subscription: public CleanupHandler 00123 { 00124 private: 00126 Mutex m_mutex; 00128 Condition m_condNotify; 00129 00131 Condition m_condFinish; 00132 00133 std::list<Referenced *> m_items; 00134 std::list<OSThread *> m_waiting; 00136 bool m_front; 00137 00139 int m_notifyAll; 00140 /* Count of subscribed threads (to spare time with trespect to list::size()*/ 00141 int m_subscribed; 00142 /* Count of ready items */ 00143 int m_notifies; 00146 int m_limbo; 00147 00148 bool subscribeInternal( double time, Referenced **result ); 00149 00150 protected: 00151 00170 virtual inline bool subscriberCanGo( OSThread &pself ) 00171 { 00172 return (m_front && pself.equal(**(m_waiting.begin() ) ))|| ! m_front; 00173 } 00174 00205 void limboSubscribe(); 00206 00207 public: 00218 Subscription( bool fairPolicy = true); 00219 00242 bool subscribe( double time = -1.0, Referenced **result=0 ); 00243 00253 bool subscribeNow( double time = -1.0, Referenced ** result=0 ); 00254 00258 bool subscribe(Referenced ** result ) { return subscribe( -1.0, result ); } 00259 00263 bool subscribeNow(Referenced ** result ) { return subscribeNow( -1.0, result ); } 00264 00275 void notify( Referenced *data = 0 ); 00276 00292 void notifyAll( Referenced *data = 0 ); 00293 00298 int subscribers() { return m_subscribed; } 00299 00307 void setPolicy( bool fair ) 00308 { 00309 m_mutex.lock(); 00310 m_front = fair; // some subscriber may have waited for that. 00311 if ( m_subscribed > 0 ) 00312 m_condNotify.signal(); 00313 m_mutex.unlock(); 00314 } 00315 00319 virtual void handleCleanup( int, void * ); 00320 }; 00321 00322 } 00323 00324 #endif 00325 /* end of wefts_subscription.h */