00001 /********************************************************************\ 00002 00003 Name: RootLock.cxx 00004 Created by: Konstantin Olchanski 00005 00006 Contents: Helper functions for locking ROOT access in multithreaded network servers 00007 00008 $Id$ 00009 00010 \********************************************************************/ 00011 00012 #include "RootLock.h" 00013 00014 #include <TSemaphore.h> 00015 #include <TTimer.h> 00016 00017 static TSemaphore gRootSema(0); // wait by server, post by timer 00018 static TSemaphore gWaitSema(0); // post by server, wait by timer 00019 static TSemaphore gDoneSema(0); // post by server, wait by timer 00020 00021 bool gDebugLockRoot = false; 00022 00023 void LockRoot() 00024 { 00025 if (gDebugLockRoot) 00026 printf("Try Lock ROOT!\n"); 00027 gWaitSema.Post(); 00028 gRootSema.Wait(); 00029 if (gDebugLockRoot) 00030 printf("Lock ROOT!\n"); 00031 } 00032 00033 void UnlockRoot() 00034 { 00035 if (gDebugLockRoot) 00036 printf("Unlock ROOT!\n"); 00037 gDoneSema.Post(); 00038 } 00039 00040 LockRootGuard::LockRootGuard() // ctor 00041 { 00042 fLocked = true; 00043 LockRoot(); 00044 } 00045 00046 LockRootGuard::~LockRootGuard() // dtor 00047 { 00048 if (fLocked) 00049 Unlock(); 00050 } 00051 00052 void LockRootGuard::Unlock() 00053 { 00054 UnlockRoot(); 00055 fLocked = false; 00056 } 00057 00058 class ServerTimer : public TTimer 00059 { 00060 public: 00061 00062 static ServerTimer* fgTimer; 00063 00064 static void StartServerTimer(int period_msec = 100) 00065 { 00066 if (!fgTimer) 00067 { 00068 fgTimer = new ServerTimer(); 00069 fgTimer->Start(period_msec,kTRUE); 00070 } 00071 } 00072 00073 Bool_t Notify() 00074 { 00075 if (gDebugLockRoot) 00076 fprintf(stderr, "ServerTimer::Notify!!\n"); 00077 00078 int notWaiting = gWaitSema.TryWait(); 00079 if (gDebugLockRoot) 00080 printf("NotWaiting %d!\n", notWaiting); 00081 if (!notWaiting) 00082 { 00083 if (gDebugLockRoot) 00084 printf("Yeld root sema!\n"); 00085 gRootSema.Post(); 00086 TThread::Self()->Sleep(0, 1000000); // sleep in ns 00087 gDoneSema.Wait(); 00088 if (gDebugLockRoot) 00089 printf("Recapture root sema!\n"); 00090 } 00091 00092 Reset(); 00093 return kTRUE; 00094 } 00095 00096 private: 00097 // ServerTimer is a singleton class, 00098 // thus ctor and dtor are private 00099 00100 ~ServerTimer() // dtor 00101 { 00102 //TurnOff(); 00103 } 00104 00105 ServerTimer() // ctor 00106 { 00107 //int period_msec = 100; 00108 //Start(period_msec,kTRUE); 00109 } 00110 }; 00111 00112 ServerTimer* ServerTimer::fgTimer; 00113 00114 void StartLockRootTimer(int period_msec) 00115 { 00116 ServerTimer::StartServerTimer(period_msec); 00117 } 00118 00119 // end file