2 * Copyright 2000, International Business Machines Corporation and others.
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
14 #include <afs/param.h>
18 #include <WINNT/afsapplib.h>
22 * VARIABLES __________________________________________________________________
26 static LPTASKQUEUE_PARAMS ptqp
= NULL
;
28 typedef struct TASKQUEUEITEM
30 struct TASKQUEUEITEM
*pNext
;
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
)
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
)
79 static BOOL fStarted
= FALSE
;
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
)))
99 if ((hThread
= CreateThread (NULL
, 0, (LPTHREAD_START_ROUTINE
)Task_ThreadProc
, 0, 0, &dwThreadID
)) != NULL
)
101 SetThreadPriority (hThread
, THREAD_PRIORITY_BELOW_NORMAL
);
107 LPTASKQUEUEITEM lptqi
= New (TASKQUEUEITEM
);
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
;
133 EnterCriticalSection (&csTaskQueue
);
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
;
153 // is this thread unnecessary?--that is, if we couldn't find anything
154 // to do, then kill off all threads.
159 LeaveCriticalSection (&csTaskQueue
);
163 LeaveCriticalSection (&csTaskQueue
);
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
);