93 class TGWin32CallBackObject :
public TObject {
98 TGWin32CallBackObject(
TGWin32CallBack cb,
void *p):fCallBack(cb),fParam(p) {}
99 ~TGWin32CallBackObject() {
if (fParam)
delete fParam; }
103 class TGWin32ProxyBasePrivate {
106 TGWin32ProxyBasePrivate();
107 ~TGWin32ProxyBasePrivate();
113 TGWin32ProxyBasePrivate::TGWin32ProxyBasePrivate()
115 fEvent = ::CreateEvent(
NULL, TRUE, FALSE,
NULL);
121 TGWin32ProxyBasePrivate::~TGWin32ProxyBasePrivate()
123 if (fEvent) ::CloseHandle(fEvent);
128 ULong_t TGWin32ProxyBase::fgPostMessageId = 0;
129 ULong_t TGWin32ProxyBase::fgPingMessageId = 0;
130 ULong_t TGWin32ProxyBase::fgMainThreadId = 0;
131 ULong_t TGWin32ProxyBase::fgUserThreadId = 0;
132 Long_t TGWin32ProxyBase::fgLock = 0;
133 UInt_t TGWin32ProxyBase::fMaxResponseTime = 0;
144 fListOfCallBacks =
new TList();
146 fId = ::GetCurrentThreadId();
147 fPimpl =
new TGWin32ProxyBasePrivate();
149 if (!fgPostMessageId) fgPostMessageId = ::RegisterWindowMessage(
"TGWin32ProxyBase::Post");
150 if (!fgPingMessageId) fgPingMessageId = ::RegisterWindowMessage(
"TGWin32ProxyBase::Ping");
158 fListOfCallBacks->Delete();
159 delete fListOfCallBacks;
160 fListOfCallBacks = 0;
186 if (IsGloballyLocked())
return;
187 ::InterlockedIncrement(&fgLock);
195 if (!IsGloballyLocked())
return;
196 ::InterlockedDecrement(&fgLock);
204 return ::PostThreadMessage(fgMainThreadId, fgPingMessageId, (WPARAM)0, 0
L);
212 static LARGE_INTEGER freq;
218 LARGE_INTEGER count0;
219 ::QueryPerformanceFrequency(&freq);
220 ::QueryPerformanceCounter(&count0);
223 dummy = ((
Double_t)count0.QuadPart - overhead)*1000./((
Double_t)freq.QuadPart);
225 ::QueryPerformanceCounter(&count);
230 ::QueryPerformanceCounter(&count);
231 return ((
Double_t)count.QuadPart - overhead)*1000./((
Double_t)freq.QuadPart);
241 if (fListOfCallBacks && fListOfCallBacks->GetSize()) {
242 TIter next(fListOfCallBacks);
243 TGWin32CallBackObject *obj;
245 while ((obj = (TGWin32CallBackObject*)next())) {
246 obj->fCallBack(obj->fParam);
250 if (fCallBack) fCallBack(fParam);
251 ::SetEvent(fPimpl->fEvent);
269 if (!fgMainThreadId)
return kFALSE;
271 while (IsGloballyLocked()) {
273 #ifdef OLD_THREAD_IMPLEMENTATION 274 if (GetCurrentThreadId() == fgMainThreadId)
278 if (!fgMainThreadId)
return kFALSE;
281 Bool_t batch = !sync && (fListOfCallBacks->GetSize() < fBatchLimit);
285 if (!fgUserThreadId && fIsVirtualX &&
286 (GetCurrentThreadId() != fgMainThreadId) &&
287 (fListOfCallBacks->GetSize() < fBatchLimit))
291 fListOfCallBacks->Add(
new TGWin32CallBackObject(fCallBack, fParam));
295 while (!::PostThreadMessage(fgMainThreadId, fgPostMessageId, (WPARAM)
this, 0
L)) {
298 if (wait++ > 5)
return kFALSE;
301 #ifdef OLD_THREAD_IMPLEMENTATION 305 DWORD res = WAIT_TIMEOUT;
306 while (res == WAIT_TIMEOUT) {
307 res = ::WaitForSingleObject(fPimpl->fEvent, 100);
308 #ifdef OLD_THREAD_IMPLEMENTATION 309 if ((GetCurrentThreadId() == fgMainThreadId) ||
310 (!
gROOT->IsLineProcessing() && IsGloballyLocked())) {
313 if (cnt++ > 20)
break;
316 ::ResetEvent(fPimpl->fEvent);
318 if (res == WAIT_TIMEOUT) {
323 fListOfCallBacks->Delete();
340 ::PostThreadMessage(fgMainThreadId, WM_QUIT, 0, 0
L);
virtual void ExecuteCallBack(Bool_t sync)
Executes all batched callbacks and the latest callback This method is executed by server thread...
static void GlobalUnlock()
unlock any proxy (client thread)
RooArgList L(const RooAbsArg &v1)
virtual ~TGWin32ProxyBase()
dtor
static void Lock()
enter critical section
virtual void SendExitMessage()
send exit message to server thread
static void GlobalLock()
lock any proxy (client thread)
static RooMathCoreReg dummy
void(* TGWin32CallBack)(void *)
virtual Bool_t ForwardCallBack(Bool_t sync)
if sync is kTRUE:
Mother of all ROOT objects.
static Bool_t IsGloballyLocked()
Check the status of the lock.
virtual Double_t GetMilliSeconds()
returns elapsed time in milliseconds with microseconds precision
static Bool_t Ping()
send ping messsage to server thread
static void Unlock()
leave critical section