Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendthread.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS WinSock 2 API 00004 * FILE: dprocess.c 00005 * PURPOSE: Thread Object 00006 * PROGRAMMER: Alex Ionescu (alex@relsoft.net) 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 #include "ws2_32.h" 00011 00012 /* FUNCTIONS *****************************************************************/ 00013 00014 DWORD 00015 WSAAPI 00016 WsThreadDefaultBlockingHook(VOID) 00017 { 00018 MSG Message; 00019 BOOL GotMessage = FALSE; 00020 00021 /* Get the message */ 00022 GotMessage = PeekMessage(&Message, NULL, 0, 0, PM_REMOVE); 00023 00024 /* Check if we got one */ 00025 if (GotMessage) 00026 { 00027 /* Process it */ 00028 TranslateMessage(&Message); 00029 DispatchMessage(&Message); 00030 } 00031 00032 /* return */ 00033 return GotMessage; 00034 } 00035 00036 BOOL 00037 WSAAPI 00038 WsThreadBlockingCallback(IN DWORD_PTR Context) 00039 { 00040 PWSTHREAD Thread = TlsGetValue(TlsIndex); 00041 00042 /* Set thread as blocking, set cancel callback and the clear cancel flag */ 00043 Thread->Blocking = TRUE; 00044 Thread->CancelBlockingCall = (LPWSPCANCELBLOCKINGCALL)Context; 00045 Thread->Cancelled = FALSE; 00046 00047 /* Call the blocking hook */ 00048 while(Thread->BlockingHook()); 00049 00050 /* We're not blocking anymore */ 00051 Thread->Blocking = FALSE; 00052 00053 /* Return whether or not we were cancelled */ 00054 return !Thread->Cancelled; 00055 } 00056 00057 FARPROC 00058 WSAAPI 00059 WsThreadSetBlockingHook(IN PWSTHREAD Thread, 00060 IN FARPROC BlockingHook) 00061 { 00062 FARPROC OldHook = Thread->BlockingHook; 00063 00064 /* Check if we're resetting to our default hook */ 00065 if (BlockingHook == (FARPROC)WsThreadDefaultBlockingHook) 00066 { 00067 /* Clear out the blocking callback */ 00068 Thread->BlockingCallback = NULL; 00069 } 00070 else 00071 { 00072 /* Set the blocking callback */ 00073 Thread->BlockingCallback = WsThreadBlockingCallback; 00074 } 00075 00076 /* Set the new blocking hook and return the previous */ 00077 Thread->BlockingHook = BlockingHook; 00078 return OldHook; 00079 } 00080 00081 DWORD 00082 WSAAPI 00083 WsThreadUnhookBlockingHook(IN PWSTHREAD Thread) 00084 { 00085 /* Reset the hook to the default, and remove the callback */ 00086 Thread->BlockingHook = (FARPROC)WsThreadDefaultBlockingHook; 00087 Thread->BlockingCallback = NULL; 00088 00089 /* Return success */ 00090 return ERROR_SUCCESS; 00091 } 00092 00093 DWORD 00094 WSAAPI 00095 WsThreadCancelBlockingCall(IN PWSTHREAD Thread) 00096 { 00097 INT ErrorCode, ReturnValue; 00098 00099 /* Make sure that the Thread is really in a blocking call */ 00100 if (!Thread->Blocking) return WSAEINVAL; 00101 00102 /* Make sure we haven't already been cancelled */ 00103 if (!Thread->Cancelled) 00104 { 00105 /* Call the cancel procedure */ 00106 ReturnValue = Thread->CancelBlockingCall(&ErrorCode); 00107 if (ReturnValue != ERROR_SUCCESS) return ErrorCode; 00108 00109 /* Set us as cancelled */ 00110 Thread->Cancelled = TRUE; 00111 } 00112 00113 /* Success */ 00114 return ERROR_SUCCESS; 00115 } 00116 00117 PWSPROTO_BUFFER 00118 WSAAPI 00119 WsThreadGetProtoBuffer(IN PWSTHREAD Thread) 00120 { 00121 /* See if it already exists */ 00122 if (!Thread->ProtocolInfo) 00123 { 00124 /* We don't have a buffer; allocate it */ 00125 Thread->ProtocolInfo = HeapAlloc(WsSockHeap, 0, sizeof(PWSPROTO_BUFFER)); 00126 } 00127 00128 /* Return it */ 00129 return Thread->ProtocolInfo; 00130 } 00131 00132 PWSTHREAD 00133 WSAAPI 00134 WsThreadAllocate(VOID) 00135 { 00136 PWSTHREAD Thread; 00137 00138 /* Allocate the object */ 00139 Thread = HeapAlloc(WsSockHeap, HEAP_ZERO_MEMORY, sizeof(*Thread)); 00140 00141 /* Set non-zero data */ 00142 Thread->BlockingHook = (FARPROC)WsThreadDefaultBlockingHook; 00143 00144 /* Return it */ 00145 return Thread; 00146 } 00147 00148 DWORD 00149 WSAAPI 00150 WsThreadStartup(VOID) 00151 { 00152 INT ErrorCode = WSASYSCALLFAILURE; 00153 00154 /* Check if we have a valid TLS */ 00155 if (TlsIndex != TLS_OUT_OF_INDEXES) 00156 { 00157 /* TLS was already OK */ 00158 ErrorCode = ERROR_SUCCESS; 00159 } 00160 00161 /* Return */ 00162 return ErrorCode; 00163 } 00164 00165 VOID 00166 WSAAPI 00167 WsThreadCleanup(VOID) 00168 { 00169 } 00170 00171 DWORD 00172 WSAAPI 00173 WsThreadInitialize(IN PWSTHREAD Thread, 00174 IN PWSPROCESS Process) 00175 { 00176 INT ErrorCode = WSASYSCALLFAILURE; 00177 00178 /* Set the process */ 00179 Thread->Process = Process; 00180 00181 /* Get the helper device */ 00182 if ((WsProcGetAsyncHelper(Process, &Thread->AsyncHelper)) == ERROR_SUCCESS) 00183 { 00184 /* Initialize a WAH Thread ID */ 00185 if ((WahOpenCurrentThread(Thread->AsyncHelper, 00186 &Thread->WahThreadId)) == ERROR_SUCCESS) 00187 { 00188 /* Success */ 00189 ErrorCode = ERROR_SUCCESS; 00190 } 00191 } 00192 00193 /* Return */ 00194 return ErrorCode; 00195 } 00196 00197 VOID 00198 WSAAPI 00199 WsThreadDelete(IN PWSTHREAD Thread) 00200 { 00201 /* Remove the blocking hook */ 00202 Thread->BlockingHook = NULL; 00203 00204 /* Free our buffers */ 00205 if (Thread->Hostent) HeapFree(WsSockHeap, 0, Thread->Hostent); 00206 if (Thread->Servent) HeapFree(WsSockHeap, 0, Thread->Servent); 00207 if (Thread->ProtocolInfo) HeapFree(WsSockHeap, 0, Thread->ProtocolInfo); 00208 00209 /* Clear the TLS */ 00210 TlsSetValue(TlsIndex, NULL); 00211 00212 /* Close the WAH Handle */ 00213 WahCloseThread(Thread->AsyncHelper, &Thread->WahThreadId); 00214 00215 /* Unlink the process and free us */ 00216 Thread->Process = NULL; 00217 HeapFree(WsSockHeap, 0, Thread); 00218 } 00219 00220 VOID 00221 WSAAPI 00222 WsThreadDestroyCurrentThread(VOID) 00223 { 00224 PWSTHREAD Thread; 00225 00226 /* Make sure we have TLS */ 00227 if (TlsIndex != TLS_OUT_OF_INDEXES) 00228 { 00229 /* Get the thread */ 00230 if ((Thread = TlsGetValue(TlsIndex))) 00231 { 00232 /* Delete it */ 00233 WsThreadDelete(Thread); 00234 TlsSetValue(TlsIndex, 0); 00235 } 00236 } 00237 } 00238 00239 DWORD 00240 WSAAPI 00241 WsThreadCreate(IN PWSPROCESS Process, 00242 IN PWSTHREAD *CurrentThread) 00243 { 00244 PWSTHREAD Thread = NULL; 00245 INT ErrorCode = WSASYSCALLFAILURE; 00246 00247 /* Make sure we have TLS */ 00248 if (TlsIndex != TLS_OUT_OF_INDEXES) 00249 { 00250 /* Allocate the thread */ 00251 if ((Thread = WsThreadAllocate())) 00252 { 00253 /* Initialize it */ 00254 if (WsThreadInitialize(Thread, Process) == ERROR_SUCCESS) 00255 { 00256 /* Set the TLS */ 00257 if (TlsSetValue(TlsIndex, Thread)) 00258 { 00259 /* Return it and success */ 00260 *CurrentThread = Thread; 00261 ErrorCode = ERROR_SUCCESS; 00262 } 00263 } 00264 00265 /* Check for any failures */ 00266 if (ErrorCode != ERROR_SUCCESS) WsThreadDelete(Thread); 00267 } 00268 } 00269 00270 /* Return */ 00271 return ErrorCode; 00272 } 00273 00274 DWORD 00275 WSAAPI 00276 WsThreadGetCurrentThread(IN PWSPROCESS Process, 00277 IN PWSTHREAD *Thread) 00278 { 00279 /* Get the thread */ 00280 if ((*Thread = TlsGetValue(TlsIndex))) 00281 { 00282 /* Success */ 00283 return ERROR_SUCCESS; 00284 } 00285 else 00286 { 00287 /* We failed, initialize it */ 00288 return WsThreadCreate(Process, Thread); 00289 } 00290 } 00291 00292 LPWSATHREADID 00293 WSAAPI 00294 WsThreadGetThreadId(IN PWSPROCESS Process) 00295 { 00296 PWSTHREAD Thread; 00297 00298 /* Get the thread */ 00299 if ((Thread = TlsGetValue(TlsIndex))) 00300 { 00301 /* Return the ID */ 00302 return &Thread->WahThreadId; 00303 } 00304 else 00305 { 00306 /* Not a valid thread */ 00307 return NULL; 00308 } 00309 } 00310 00311 PHOSTENT 00312 WSAAPI 00313 WsThreadBlobToHostent(IN PWSTHREAD Thread, 00314 IN LPBLOB Blob) 00315 { 00316 /* Check if our buffer is too small */ 00317 if (Thread->HostentSize < Blob->cbSize) 00318 { 00319 /* Delete the current buffer and allocate a new one */ 00320 HeapFree(WsSockHeap, 0, Thread->Hostent); 00321 Thread->Hostent = HeapAlloc(WsSockHeap, 0, Blob->cbSize); 00322 00323 /* Set the new size */ 00324 Thread->HostentSize = Blob->cbSize; 00325 } 00326 00327 /* Do we have a buffer? */ 00328 if (Thread->Hostent) 00329 { 00330 /* Copy the data inside */ 00331 RtlMoveMemory(Thread->Hostent, Blob->pBlobData, Blob->cbSize); 00332 } 00333 else 00334 { 00335 /* No buffer space! */ 00336 Thread->HostentSize = 0; 00337 SetLastError(WSA_NOT_ENOUGH_MEMORY); 00338 } 00339 00340 /* Return the buffer */ 00341 return (PHOSTENT)Thread->Hostent; 00342 } 00343 00344 PSERVENT 00345 WSAAPI 00346 WsThreadBlobToServent(IN PWSTHREAD Thread, 00347 IN LPBLOB Blob) 00348 { 00349 /* Check if our buffer is too small */ 00350 if (Thread->ServentSize < Blob->cbSize) 00351 { 00352 /* Delete the current buffer and allocate a new one */ 00353 HeapFree(WsSockHeap, 0, Thread->Servent); 00354 Thread->Servent = HeapAlloc(WsSockHeap, 0, Blob->cbSize); 00355 00356 /* Set the new size */ 00357 Thread->ServentSize = Blob->cbSize; 00358 } 00359 00360 /* Do we have a buffer? */ 00361 if (Thread->Servent) 00362 { 00363 /* Copy the data inside */ 00364 RtlMoveMemory(Thread->Servent, Blob->pBlobData, Blob->cbSize); 00365 } 00366 else 00367 { 00368 /* No buffer space! */ 00369 Thread->ServentSize = 0; 00370 SetLastError(WSA_NOT_ENOUGH_MEMORY); 00371 } 00372 00373 /* Return the buffer */ 00374 return (PSERVENT)Thread->Servent; 00375 } 00376 Generated on Sat May 26 2012 04:25:39 for ReactOS by
1.7.6.1
|