Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / WINNT / afsapplib / al_task.cpp
blob5d142a6c3cf45126f6b89c4ca03e24ec8466caa8
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
10 #include <winsock2.h>
11 #include <ws2tcpip.h>
13 extern "C" {
14 #include <afs/param.h>
15 #include <afs/stds.h>
18 #include <WINNT/afsapplib.h>
22 * VARIABLES __________________________________________________________________
26 static LPTASKQUEUE_PARAMS ptqp = NULL;
28 typedef struct TASKQUEUEITEM
30 struct TASKQUEUEITEM *pNext;
31 int idTask;
32 HWND hReply;
33 PVOID lpUser;
34 } TASKQUEUEITEM, *LPTASKQUEUEITEM;
36 static LPTASKQUEUEITEM pTaskQueuePop = NULL;
37 static LPTASKQUEUEITEM pTaskQueuePushAfter = NULL;
38 static CRITICAL_SECTION csTaskQueue;
40 static size_t nThreadsRunning = 0;
41 static size_t nRequestsActive = 0;
46 * PROTOTYPES _________________________________________________________________
50 DWORD WINAPI Task_ThreadProc (PVOID lp);
54 * ROUTINES ___________________________________________________________________
58 void AfsAppLib_InitTaskQueue (LPTASKQUEUE_PARAMS lpp)
60 if (ptqp != NULL)
62 Delete (ptqp);
63 ptqp = NULL;
66 if (lpp && lpp->fnCreateTaskPacket && lpp->fnPerformTask && lpp->fnFreeTaskPacket)
68 ptqp = New (TASKQUEUE_PARAMS);
69 memcpy (ptqp, lpp, sizeof(TASKQUEUE_PARAMS));
74 void StartTask (int idTask, HWND hReply, PVOID lpUser)
76 if (!ptqp)
77 return;
79 static BOOL fStarted = FALSE;
80 if (!fStarted)
82 fStarted = TRUE;
83 InitializeCriticalSection (&csTaskQueue);
86 // Then push this notification onto our TaskQueue, so that the task
87 // thread will pop off each request in turn and take a look at it.
88 // Ideally, PostThreadMessage() and GetMessage() would implement all this
89 // garbage, but that doesn't work properly for some reason...
91 EnterCriticalSection (&csTaskQueue);
93 if ((++nRequestsActive) > nThreadsRunning)
95 if ((!ptqp->nThreadsMax) || (nThreadsRunning < (size_t)(ptqp->nThreadsMax)))
97 DWORD dwThreadID;
98 HANDLE hThread;
99 if ((hThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)Task_ThreadProc, 0, 0, &dwThreadID)) != NULL)
101 SetThreadPriority (hThread, THREAD_PRIORITY_BELOW_NORMAL);
102 ++nThreadsRunning;
107 LPTASKQUEUEITEM lptqi = New (TASKQUEUEITEM);
108 lptqi->pNext = NULL;
109 lptqi->idTask = idTask;
110 lptqi->hReply = hReply;
111 lptqi->lpUser = lpUser;
113 if (pTaskQueuePushAfter != NULL)
114 pTaskQueuePushAfter->pNext = lptqi;
115 pTaskQueuePushAfter = lptqi;
117 if (pTaskQueuePop == NULL)
118 pTaskQueuePop = lptqi;
120 LeaveCriticalSection (&csTaskQueue);
124 DWORD WINAPI Task_ThreadProc (PVOID lp)
126 BOOL fJustDidTask = FALSE;
128 for (;;)
130 BOOL fFound = FALSE;
131 TASKQUEUEITEM tqi;
133 EnterCriticalSection (&csTaskQueue);
135 if (fJustDidTask)
137 --nRequestsActive;
138 fJustDidTask = FALSE;
141 if (pTaskQueuePop != NULL)
143 LPTASKQUEUEITEM lptqiNext = pTaskQueuePop->pNext;
144 tqi = *pTaskQueuePop;
145 Delete (pTaskQueuePop);
146 if (pTaskQueuePushAfter == pTaskQueuePop)
147 pTaskQueuePushAfter = NULL;
148 pTaskQueuePop = lptqiNext;
149 fFound = TRUE;
150 fJustDidTask = TRUE;
153 // is this thread unnecessary?--that is, if we couldn't find anything
154 // to do, then kill off all threads.
156 if (!fFound)
158 --nThreadsRunning;
159 LeaveCriticalSection (&csTaskQueue);
160 break;
163 LeaveCriticalSection (&csTaskQueue);
165 if (fFound)
167 LPTASKPACKET ptp;
168 if ((ptp = (*ptqp->fnCreateTaskPacket)(tqi.idTask, tqi.hReply, tqi.lpUser)) != NULL)
170 (*ptqp->fnPerformTask)(ptp);
173 if (tqi.hReply && IsWindow (tqi.hReply))
175 PostMessage (tqi.hReply, WM_ENDTASK, 0, (LPARAM)ptp);
177 else if (ptp != NULL)
179 (*ptqp->fnFreeTaskPacket)(ptp);
184 return 0;