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

nbcmdqueue.c
Go to the documentation of this file.
00001 /* Copyright (c) 2003 Juan Lang
00002  *
00003  * This library is free software; you can redistribute it and/or
00004  * modify it under the terms of the GNU Lesser General Public
00005  * License as published by the Free Software Foundation; either
00006  * version 2.1 of the License, or (at your option) any later version.
00007  *
00008  * This library is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011  * Lesser General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU Lesser General Public
00014  * License along with this library; if not, write to the Free Software
00015  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00016  */
00017 #include "config.h"
00018 #include "wine/debug.h"
00019 #include "nbcmdqueue.h"
00020 
00021 WINE_DEFAULT_DEBUG_CHANNEL(netbios);
00022 
00023 struct NBCmdQueue
00024 {
00025     HANDLE           heap;
00026     CRITICAL_SECTION cs;
00027     PNCB             head;
00028 };
00029 
00030 #define CANCEL_EVENT_PTR(ncb) (PHANDLE)((ncb)->ncb_reserve)
00031 #define NEXT_PTR(ncb) (PNCB *)((ncb)->ncb_reserve + sizeof(HANDLE))
00032 
00033 /* The reserved area of an ncb will be used for the following data:
00034  * - a cancelled flag (BOOL, 4 bytes??)
00035  * - a handle to an event that's set by a cancelled command on completion
00036  *   (HANDLE, 4 bytes)
00037  * These members are used in the following way
00038  * - on cancel, set the event member of the reserved field (with create event)
00039  * - NBCmdComplete will delete the ncb from the queue of there's no event;
00040  *   otherwise it will set the event and not delete the ncb
00041  * - cancel must lock the queue before finding the ncb in it, and can unlock it
00042  *   once it's set the event (and the cancelled flag)
00043  * - NBCmdComplete must lock the queue before attempting to remove the ncb or
00044  *   check the event
00045  * - NBCmdQueueCancelAll will lock the queue, and cancel all ncb's in the queue.
00046  *   It'll then unlock the queue, and wait on the event in the head of the queue
00047  *   until there's no more ncb's in the queue.
00048  * Space optimization: use the handle as a boolean.  NULL == 0 => not cancelled.
00049  * Non-NULL == valid handle => cancelled.  This allows storing a next pointer
00050  * in the ncb's reserved field as well, avoiding a memory alloc for a new
00051  * command (cool).
00052  */
00053 
00054 struct NBCmdQueue *NBCmdQueueCreate(HANDLE heap)
00055 {
00056     struct NBCmdQueue *queue;
00057 
00058     if (heap == NULL)
00059         heap = GetProcessHeap();
00060     queue = HeapAlloc(heap, 0, sizeof(struct NBCmdQueue));
00061     if (queue)
00062     {
00063         queue->heap = heap;
00064         InitializeCriticalSection(&queue->cs);
00065         queue->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": NBCmdQueue.cs");
00066         queue->head = NULL;
00067     }
00068     return queue;
00069 }
00070 
00071 UCHAR NBCmdQueueAdd(struct NBCmdQueue *queue, PNCB ncb)
00072 {
00073     UCHAR ret;
00074 
00075     TRACE(": queue %p, ncb %p\n", queue, ncb);
00076 
00077     if (!queue)
00078         return NRC_BADDR;
00079     if (!ncb)
00080         return NRC_INVADDRESS;
00081 
00082     *CANCEL_EVENT_PTR(ncb) = NULL;
00083     EnterCriticalSection(&queue->cs);
00084     *NEXT_PTR(ncb) = queue->head;
00085     queue->head = ncb;
00086     ret = NRC_GOODRET;
00087     LeaveCriticalSection(&queue->cs);
00088     TRACE("returning 0x%02x\n", ret);
00089     return ret;
00090 }
00091 
00092 static PNCB *NBCmdQueueFindNBC(struct NBCmdQueue *queue, PNCB ncb)
00093 {
00094     PNCB *ret;
00095 
00096     if (!queue || !ncb)
00097         ret = NULL;
00098     else
00099     {
00100         ret = &queue->head;
00101         while (ret && *ret != ncb)
00102             ret = NEXT_PTR(*ret);
00103     }
00104     return ret;
00105 }
00106 
00107 UCHAR NBCmdQueueCancel(struct NBCmdQueue *queue, PNCB ncb)
00108 {
00109     UCHAR ret;
00110     PNCB *spot;
00111 
00112     TRACE(": queue %p, ncb %p\n", queue, ncb);
00113 
00114     if (!queue)
00115         return NRC_BADDR;
00116     if (!ncb)
00117         return NRC_INVADDRESS;
00118 
00119     EnterCriticalSection(&queue->cs);
00120     spot = NBCmdQueueFindNBC(queue, ncb);
00121     if (spot)
00122     {
00123         *CANCEL_EVENT_PTR(*spot) = CreateEventW(NULL, FALSE, FALSE, NULL);
00124         WaitForSingleObject(*CANCEL_EVENT_PTR(*spot), INFINITE);
00125         CloseHandle(*CANCEL_EVENT_PTR(*spot));
00126         *spot = *NEXT_PTR(*spot);
00127         if (ncb->ncb_retcode == NRC_CMDCAN)
00128             ret = NRC_CMDCAN;
00129         else
00130             ret = NRC_CANOCCR;
00131     }
00132     else
00133         ret = NRC_INVADDRESS;
00134     LeaveCriticalSection(&queue->cs);
00135     TRACE("returning 0x%02x\n", ret);
00136     return ret;
00137 }
00138 
00139 UCHAR NBCmdQueueComplete(struct NBCmdQueue *queue, PNCB ncb, UCHAR retcode)
00140 {
00141     UCHAR ret;
00142     PNCB *spot;
00143 
00144     TRACE(": queue %p, ncb %p\n", queue, ncb);
00145 
00146     if (!queue)
00147         return NRC_BADDR;
00148     if (!ncb)
00149         return NRC_INVADDRESS;
00150 
00151     EnterCriticalSection(&queue->cs);
00152     spot = NBCmdQueueFindNBC(queue, ncb);
00153     if (spot)
00154     {
00155         if (*CANCEL_EVENT_PTR(*spot))
00156             SetEvent(*CANCEL_EVENT_PTR(*spot));
00157         else
00158             *spot = *NEXT_PTR(*spot);
00159         ret = NRC_GOODRET;
00160     }
00161     else
00162         ret = NRC_INVADDRESS;
00163     LeaveCriticalSection(&queue->cs);
00164     TRACE("returning 0x%02x\n", ret);
00165     return ret;
00166 }
00167 
00168 UCHAR NBCmdQueueCancelAll(struct NBCmdQueue *queue)
00169 {
00170     UCHAR ret;
00171 
00172     TRACE(": queue %p\n", queue);
00173 
00174     if (!queue)
00175         return NRC_BADDR;
00176 
00177     EnterCriticalSection(&queue->cs);
00178     while (queue->head)
00179     {
00180         TRACE(": waiting for ncb %p (command 0x%02x)\n", queue->head,
00181          queue->head->ncb_command);
00182         NBCmdQueueCancel(queue, queue->head);
00183     }
00184     LeaveCriticalSection(&queue->cs);
00185     ret = NRC_GOODRET;
00186     TRACE("returning 0x%02x\n", ret);
00187     return ret;
00188 }
00189 
00190 void NBCmdQueueDestroy(struct NBCmdQueue *queue)
00191 {
00192     TRACE(": queue %p\n", queue);
00193 
00194     if (queue)
00195     {
00196         NBCmdQueueCancelAll(queue);
00197         queue->cs.DebugInfo->Spare[0] = 0;
00198         DeleteCriticalSection(&queue->cs);
00199         HeapFree(queue->heap, 0, queue);
00200     }
00201 }

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