Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TWin32Thread.cxx
Go to the documentation of this file.
1 // @(#)root/thread:$Id$
2 // Author: Bertrand Bellenot 20/10/2004
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////
13 // //
14 // TWin32Thread //
15 // //
16 // This class provides an interface to the win32 thread routines. //
17 // //
18 //////////////////////////////////////////////////////////////////////////
19 
20 #include "TWin32Thread.h"
21 #include <process.h>
22 #include <errno.h>
23 
24 ClassImp(TWin32Thread);
25 
26 ////////////////////////////////////////////////////////////////////////////////
27 /// Win32 threads -- spawn new thread (like pthread_create).
28 /// Win32 has a thread handle in addition to the thread ID.
29 
30 Int_t TWin32Thread::Run(TThread *th)
31 {
32  DWORD dwThreadId;
33  HANDLE hHandle = CreateThread(0, 0,
34  (LPTHREAD_START_ROUTINE)&TThread::Function,
35  th, 0, (DWORD*)&dwThreadId);
36  if (th->fDetached) {
37  ::CloseHandle(hHandle);
38  th->fHandle = 0L;
39  } else
40  th->fHandle = (Long_t)hHandle;
41 
42  th->fId = dwThreadId;
43 
44  return hHandle ? 0 : EINVAL;
45 }
46 
47 ////////////////////////////////////////////////////////////////////////////////
48 /// Wait for specified thread execution (if any) to complete
49 /// (like pthread_join).
50 
51 Int_t TWin32Thread::Join(TThread *th, void **ret)
52 {
53  DWORD R = WaitForSingleObject((HANDLE)th->fHandle, INFINITE);
54 
55  if ( (R == WAIT_OBJECT_0) || (R == WAIT_ABANDONED) ) {
56  //::CloseHandle((HANDLE)th->fHandle);
57  return 0;
58  }
59  if ( R == WAIT_TIMEOUT )
60  return EAGAIN;
61  return EINVAL;
62 }
63 
64 ////////////////////////////////////////////////////////////////////////////////
65 /// Exit the thread.
66 
67 Int_t TWin32Thread::Exit(void *ret)
68 {
69  ExitThread(0);
70  return 0;
71 }
72 
73 ////////////////////////////////////////////////////////////////////////////////
74 /// This is a somewhat dangerous function; it's not
75 /// suggested to Stop() threads a lot.
76 
77 Int_t TWin32Thread::Kill(TThread *th)
78 {
79  if (TerminateThread((HANDLE)th->fHandle,0)) {
80  th->fState = TThread::kCanceledState;
81  return 0;
82  }
83  return EINVAL;
84 }
85 
86 ////////////////////////////////////////////////////////////////////////////////
87 
88 Int_t TWin32Thread::CleanUpPush(void **main, void *free,void *arg)
89 {
90  if (!free) fprintf(stderr, "CleanUpPush ***ERROR*** Routine=0\n");
91  new TWin32ThreadCleanUp(main,free,arg);
92  return 0;
93 }
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 
97 Int_t TWin32Thread::CleanUpPop(void **main,Int_t exe)
98 {
99  if (!*main) return 1;
100  TWin32ThreadCleanUp *l = (TWin32ThreadCleanUp*)(*main);
101  if (!l->fRoutine) fprintf(stderr,"CleanUpPop ***ERROR*** Routine=0\n");
102  if (exe && l->fRoutine) ((void (*)(void*))(l->fRoutine))(l->fArgument);
103  *main = l->fNext; delete l;
104  return 0;
105 }
106 
107 ////////////////////////////////////////////////////////////////////////////////
108 
109 Int_t TWin32Thread::CleanUp(void **main)
110 {
111  fprintf(stderr," CleanUp %lx\n",(ULong_t)*main);
112  while(!CleanUpPop(main,1)) { }
113  return 0;
114 }
115 
116 ////////////////////////////////////////////////////////////////////////////////
117 /// Return the current thread's ID.
118 
119 Long_t TWin32Thread::SelfId()
120 {
121  return (Long_t)::GetCurrentThreadId();
122 }
123 
124 ////////////////////////////////////////////////////////////////////////////////
125 
126 Int_t TWin32Thread::SetCancelOff()
127 {
128  if (gDebug)
129  Warning("SetCancelOff", "Not implemented on Win32");
130  return 0;
131 }
132 
133 ////////////////////////////////////////////////////////////////////////////////
134 
135 Int_t TWin32Thread::SetCancelOn()
136 {
137  if (gDebug)
138  Warning("SetCancelOn", "Not implemented on Win32");
139  return 0;
140 }
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 
144 Int_t TWin32Thread::SetCancelAsynchronous()
145 {
146  if (gDebug)
147  Warning("SetCancelAsynchronous", "Not implemented on Win32");
148  return 0;
149 }
150 
151 ////////////////////////////////////////////////////////////////////////////////
152 
153 Int_t TWin32Thread::SetCancelDeferred()
154 {
155  if (gDebug)
156  Warning("SetCancelDeferred", "Not implemented on Win32");
157  return 0;
158 }
159 
160 ////////////////////////////////////////////////////////////////////////////////
161 
162 Int_t TWin32Thread::CancelPoint()
163 {
164  if (gDebug)
165  Warning("CancelPoint", "Not implemented on Win32");
166  return 0;
167 }
168 
169 // Clean Up section. PTHREAD implementations of cleanup after cancel are
170 // too different and often too bad. Temporary I invent my own bicycle.
171 // V.Perev.
172 
173 ////////////////////////////////////////////////////////////////////////////////
174 
175 TWin32ThreadCleanUp::TWin32ThreadCleanUp(void **main, void *routine, void *arg)
176 {
177  fNext = (TWin32ThreadCleanUp*)*main;
178  fRoutine = routine; fArgument = arg;
179  *main = this;
180 }