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

wait.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS CSR Sub System
00004  * FILE:            subsys/csr/csrsrv/wait.c
00005  * PURPOSE:         CSR Server DLL Wait Implementation
00006  * PROGRAMMERS:     Emanuele Aliberti
00007  *                  Alex Ionescu (alex@relsoft.net)
00008  */
00009 
00010 /* INCLUDES ******************************************************************/
00011 
00012 #include "srv.h"
00013 
00014 #define NDEBUG
00015 #include <debug.h>
00016 
00017 /* DATA **********************************************************************/
00018 
00019 RTL_CRITICAL_SECTION CsrWaitListsLock;
00020 
00021 /* PRIVATE FUNCTIONS *********************************************************/
00022 
00023 /*++
00024  * @name CsrInitializeWait
00025  *
00026  * The CsrInitializeWait routine initializes a CSR Wait Object.
00027  *
00028  * @param WaitFunction
00029  *        Pointer to the function that will handle this wait.
00030  *
00031  * @param CsrWaitThread
00032  *        Pointer to the CSR Thread that will perform the wait.
00033  *
00034  * @param WaitApiMessage
00035  *        Pointer to the CSR API Message associated to this wait.
00036  *
00037  * @param WaitContext
00038  *        Pointer to a user-defined parameter associated to this wait.
00039  *
00040  * @param NewWaitBlock
00041  *        Pointed to the initialized CSR Wait Block for this wait.
00042  *
00043  * @return TRUE in case of success, FALSE othwerwise.
00044  *
00045  * @remarks None.
00046  *
00047  *--*/
00048 BOOLEAN
00049 NTAPI
00050 CsrInitializeWait(IN CSR_WAIT_FUNCTION WaitFunction,
00051                   IN PCSR_THREAD CsrWaitThread,
00052                   IN OUT PCSR_API_MESSAGE WaitApiMessage,
00053                   IN PVOID WaitContext,
00054                   OUT PCSR_WAIT_BLOCK *NewWaitBlock)
00055 {
00056     ULONG Size;
00057     PCSR_WAIT_BLOCK WaitBlock;
00058 
00059     /* Calculate the size of the wait block */
00060     Size = sizeof(CSR_WAIT_BLOCK) -
00061            sizeof(WaitBlock->WaitApiMessage) +
00062            WaitApiMessage->Header.u1.s1.TotalLength;
00063 
00064     /* Allocate the Wait Block */
00065     WaitBlock = RtlAllocateHeap(CsrHeap, 0, Size);
00066     if (!WaitBlock)
00067     {
00068         /* Fail */
00069         WaitApiMessage->Status = STATUS_NO_MEMORY;
00070         return FALSE;
00071     }
00072 
00073     /* Initialize it */
00074     WaitBlock->Size = Size;
00075     WaitBlock->WaitThread = CsrWaitThread;
00076     WaitBlock->WaitContext = WaitContext;
00077     WaitBlock->WaitFunction = WaitFunction;
00078     WaitBlock->UserWaitList.Flink = NULL;
00079     WaitBlock->UserWaitList.Blink = NULL;
00080     WaitBlock->WaitList = WaitBlock->UserWaitList;
00081 
00082     /* Copy the message */
00083     RtlMoveMemory(&WaitBlock->WaitApiMessage,
00084                   WaitApiMessage,
00085                   WaitApiMessage->Header.u1.s1.TotalLength);
00086 
00087     /* Return the block */
00088     *NewWaitBlock = WaitBlock;
00089     return TRUE;
00090 }
00091 
00092 /*++
00093  * @name CsrNotifyWaitBlock
00094  *
00095  * The CsrNotifyWaitBlock routine calls the wait function for a registered
00096  * CSR Wait Block, and replies to the attached CSR API Message, if any.
00097  *
00098  * @param WaitBlock
00099  *        Pointer to the CSR Wait Block
00100  *
00101  * @param WaitList
00102  *        Pointer to the wait list for this wait.
00103  *
00104  * @param WaitArgument[1-2]
00105  *        User-defined values to pass to the wait function.
00106  *
00107  * @param WaitFlags
00108  *        Wait flags for this wait.
00109  *
00110  * @param DereferenceThread
00111  *        Specifies whether the CSR Thread should be dereferenced at the
00112  *        end of this wait.
00113  *
00114  * @return TRUE in case of success, FALSE otherwise.
00115  *
00116  * @remarks After a wait block is notified, the wait function becomes invalid.
00117  *
00118  *--*/
00119 BOOLEAN
00120 NTAPI
00121 CsrNotifyWaitBlock(IN PCSR_WAIT_BLOCK WaitBlock,
00122                    IN PLIST_ENTRY WaitList,
00123                    IN PVOID WaitArgument1,
00124                    IN PVOID WaitArgument2,
00125                    IN ULONG WaitFlags,
00126                    IN BOOLEAN DereferenceThread)
00127 {
00128     /* Call the wait function */
00129     if ((WaitBlock->WaitFunction)(WaitList,
00130                                   WaitBlock->WaitThread,
00131                                   &WaitBlock->WaitApiMessage,
00132                                   WaitBlock->WaitContext,
00133                                   WaitArgument1,
00134                                   WaitArgument2,
00135                                   WaitFlags))
00136     {
00137         /* The wait is done, clear the block */
00138         WaitBlock->WaitThread->WaitBlock = NULL;
00139 
00140         /* Check for captured arguments */
00141         if (WaitBlock->WaitApiMessage.CsrCaptureData)
00142         {
00143             /* Release them */
00144             CsrReleaseCapturedArguments(&WaitBlock->WaitApiMessage);
00145         }
00146 
00147         /* Reply to the port */
00148         NtReplyPort(WaitBlock->WaitThread->Process->ClientPort,
00149                     (PPORT_MESSAGE)&WaitBlock->WaitApiMessage);
00150 
00151         /* Check if we should dereference the thread */
00152         if (DereferenceThread)
00153         {
00154             /* Remove it from the Wait List */
00155             if (WaitBlock->WaitList.Flink)
00156             {
00157                 RemoveEntryList(&WaitBlock->WaitList);
00158             }
00159 
00160             /* Remove it from the User Wait List */
00161             if (WaitBlock->UserWaitList.Flink)
00162             {
00163                 RemoveEntryList(&WaitBlock->UserWaitList);
00164             }
00165 
00166             /* Dereference teh thread */
00167             CsrDereferenceThread(WaitBlock->WaitThread);
00168 
00169             /* Free the wait block */
00170             RtlFreeHeap(CsrHeap, 0, WaitBlock);
00171         }
00172         else
00173         {
00174             /* The wait is complete, but the thread is being kept alive */
00175             WaitBlock->WaitFunction = NULL;
00176         }
00177     
00178         /* The wait suceeded */
00179         return TRUE;
00180     }
00181     
00182     /* The wait failed */
00183     return FALSE;
00184 }
00185 
00186 /* PUBLIC FUNCTIONS **********************************************************/
00187 
00188 /*++
00189  * @name CsrCreateWait
00190  * @implemented NT4
00191  *
00192  * The CsrCreateWait routine creates a CSR Wait.
00193  *
00194  * @param WaitList
00195  *        Pointer to a list entry of the waits to associate.
00196  *
00197  * @param WaitFunction
00198  *        Pointer to the function that will handle this wait.
00199  *
00200  * @param CsrWaitThread
00201  *        Pointer to the CSR Thread that will perform the wait.
00202  *
00203  * @param WaitApiMessage
00204  *        Pointer to the CSR API Message associated to this wait.
00205  *
00206  * @param WaitContext
00207  *        Pointer to a user-defined parameter associated to this wait.
00208  *
00209  * @param UserWaitList
00210  *        Pointer to a list entry of the user-defined waits to associate.
00211  *
00212  * @return TRUE in case of success, FALSE otherwise.
00213  *
00214  * @remarks None.
00215  *
00216  *--*/
00217 BOOLEAN
00218 NTAPI
00219 CsrCreateWait(IN PLIST_ENTRY WaitList,
00220               IN CSR_WAIT_FUNCTION WaitFunction,
00221               IN PCSR_THREAD CsrWaitThread,
00222               IN OUT PCSR_API_MESSAGE WaitApiMessage,
00223               IN PVOID WaitContext,
00224               IN PLIST_ENTRY UserWaitList OPTIONAL)
00225 {
00226     PCSR_WAIT_BLOCK WaitBlock;
00227 
00228     /* Initialize the wait */
00229     if (!CsrInitializeWait(WaitFunction,
00230                            CsrWaitThread,
00231                            WaitApiMessage,
00232                            WaitContext,
00233                            &WaitBlock))
00234     {
00235         return FALSE;
00236     }
00237 
00238     /* Acquire the Wait Lock */
00239     CsrAcquireWaitLock();
00240 
00241     /* Make sure the thread wasn't destroyed */
00242     if (CsrWaitThread->Flags & CsrThreadTerminated)
00243     {
00244         /* Fail the wait */
00245         RtlFreeHeap(CsrHeap, 0, WaitBlock);
00246         CsrReleaseWaitLock();
00247         return FALSE;
00248     }
00249 
00250     /* Insert the wait in the queue */
00251     InsertTailList(WaitList, &WaitBlock->WaitList);
00252 
00253     /* Insert the User Wait too, if one was given */
00254     if (UserWaitList) InsertTailList(UserWaitList, &WaitBlock->UserWaitList);
00255 
00256     /* Return */
00257     CsrReleaseWaitLock();
00258     return TRUE;
00259 }
00260 
00261 /*++
00262  * @name CsrDereferenceWait
00263  * @implemented NT4
00264  *
00265  * The CsrDereferenceWait routine derefences a CSR Wait Block.
00266  *
00267  * @param WaitList
00268  *        Pointer to the Wait List associated to the wait.
00269 
00270  * @return None.
00271  *
00272  * @remarks None.
00273  *
00274  *--*/
00275 VOID
00276 NTAPI
00277 CsrDereferenceWait(IN PLIST_ENTRY WaitList)
00278 {
00279     PLIST_ENTRY NextEntry;
00280     PCSR_WAIT_BLOCK WaitBlock;
00281 
00282     /* Acquire the Process and Wait Locks */
00283     CsrAcquireProcessLock();
00284     CsrAcquireWaitLock();
00285 
00286     /* Set the list pointers */
00287     NextEntry = WaitList->Flink;
00288 
00289     /* Start the loop */
00290     while (NextEntry != WaitList)
00291     {
00292         /* Get the wait block */
00293         WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
00294 
00295         /* Move to the next entry */
00296         NextEntry = NextEntry->Flink;
00297 
00298         /* Check if there's no Wait Routine */
00299         if (!WaitBlock->WaitFunction)
00300         {
00301             /* Remove it from the Wait List */
00302             if (WaitBlock->WaitList.Flink)
00303             {
00304                 RemoveEntryList(&WaitBlock->WaitList);
00305             }
00306 
00307             /* Remove it from the User Wait List */
00308             if (WaitBlock->UserWaitList.Flink)
00309             {
00310                 RemoveEntryList(&WaitBlock->UserWaitList);
00311             }
00312 
00313             /* Dereference the thread waiting on it */
00314             CsrDereferenceThread(WaitBlock->WaitThread);
00315 
00316             /* Free the block */
00317             RtlFreeHeap(CsrHeap, 0, WaitBlock);
00318         }
00319     }
00320 
00321     /* Release the locks */
00322     CsrReleaseWaitLock();
00323     CsrReleaseProcessLock();
00324 }
00325 
00326 /*++
00327  * @name CsrMoveSatisfiedWait
00328  * @implemented NT5
00329  *
00330  * The CsrMoveSatisfiedWait routine moves satisfied waits from a wait list
00331  * to another list entry.
00332  *
00333  * @param NewEntry
00334  *        Pointer to a list entry where the satisfied waits will be added.
00335  *
00336  * @param WaitList
00337  *        Pointer to a list entry to analyze for satisfied waits.
00338  *
00339  * @return None.
00340  *
00341  * @remarks None.
00342  *
00343  *--*/
00344 VOID
00345 NTAPI
00346 CsrMoveSatisfiedWait(IN PLIST_ENTRY NewEntry,
00347                      IN PLIST_ENTRY WaitList)
00348 {
00349     PLIST_ENTRY NextEntry;
00350     PCSR_WAIT_BLOCK WaitBlock;
00351 
00352     /* Acquire the Wait Lock */
00353     CsrAcquireWaitLock();
00354 
00355     /* Set the List pointers */
00356     NextEntry = WaitList->Flink;
00357 
00358     /* Start looping */
00359     while (NextEntry != WaitList)
00360     {
00361         /* Get the Wait block */
00362         WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
00363 
00364         /* Go to the next entry */
00365         NextEntry = NextEntry->Flink;
00366 
00367         /* Check if there is a Wait Callback */
00368         if (WaitBlock->WaitFunction)
00369         {
00370             /* Remove it from the Wait Block Queue */
00371             RemoveEntryList(&WaitBlock->WaitList);
00372 
00373             /* Insert the new entry */
00374             InsertTailList(&WaitBlock->WaitList, NewEntry);
00375         }
00376     }
00377 
00378     /* Release the wait lock */
00379     CsrReleaseWaitLock();
00380 }
00381 
00382 /*++
00383  * @name CsrNotifyWait
00384  * @implemented NT4
00385  *
00386  * The CsrNotifyWait notifies a CSR Wait Block.
00387  *
00388  * @param WaitList
00389  *        Pointer to the list entry for this wait.
00390  *
00391  * @param WaitType
00392  *        Type of the wait to perform, either WaitAny or WaitAll.
00393  *
00394  * @param WaitArgument[1-2]
00395  *        User-defined argument to pass on to the wait function.
00396  *
00397  * @return TRUE in case of success, FALSE othwerwise.
00398  *
00399  * @remarks None.
00400  *
00401  *--*/
00402 BOOLEAN
00403 NTAPI
00404 CsrNotifyWait(IN PLIST_ENTRY WaitList,
00405               IN ULONG WaitType,
00406               IN PVOID WaitArgument1,
00407               IN PVOID WaitArgument2)
00408 {
00409     PLIST_ENTRY NextEntry;
00410     PCSR_WAIT_BLOCK WaitBlock;
00411     BOOLEAN NotifySuccess = FALSE;
00412 
00413     /* Acquire the Wait Lock */
00414     CsrAcquireWaitLock();
00415 
00416     /* Set the List pointers */
00417     NextEntry = WaitList->Flink;
00418 
00419     /* Start looping */
00420     while (NextEntry != WaitList)
00421     {
00422         /* Get the Wait block */
00423         WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
00424 
00425         /* Go to the next entry */
00426         NextEntry = NextEntry->Flink;
00427 
00428         /* Check if there is a Wait Callback */
00429         if (WaitBlock->WaitFunction)
00430         {
00431             /* Notify the Waiter */
00432             NotifySuccess |= CsrNotifyWaitBlock(WaitBlock,
00433                                                 WaitList,
00434                                                 WaitArgument1,
00435                                                 WaitArgument2,
00436                                                 0,
00437                                                 FALSE);
00438             
00439             /* We've already done a wait, so leave unless this is a Wait All */
00440             if (WaitType != WaitAll) break;
00441         }
00442     }
00443 
00444     /* Release the wait lock and return */
00445     CsrReleaseWaitLock();
00446     return NotifySuccess;
00447 }
00448 
00449 /* EOF */

Generated on Sun May 27 2012 04:28:08 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.