ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dthread.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.