source: trunk/src/wsock32/new/asyncthread.cpp@ 3205

Last change on this file since 3205 was 3205, checked in by sandervl, 25 years ago

wsock32\new update

File size: 7.2 KB
Line 
1/* $Id: asyncthread.cpp,v 1.2 2000-03-23 19:21:53 sandervl Exp $ */
2
3/*
4 * Async thread help functions
5 *
6 * Copyright 2000 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * TODO: Not everything is 100% thread safe (i.e. async parameter updates)
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13#define INCL_BASE
14#include <os2wrap.h>
15#include <os2sel.h>
16#include <stdlib.h>
17#include <wprocess.h>
18#include <win32api.h>
19#include <misc.h>
20#include <string.h>
21#include <vmutex.h>
22#include "wsock32.h"
23#include "asyncthread.h"
24
25static PASYNCTHREADPARM threadList = NULL;
26static VMutex asyncThreadMutex;
27
28static void AddToQueue(PASYNCTHREADPARM pThreadParm);
29
30//******************************************************************************
31//******************************************************************************
32static void APIENTRY AsyncThread(ULONG arg)
33{
34 PASYNCTHREADPARM pThreadParm = (PASYNCTHREADPARM)arg;
35
36 pThreadParm->asyncProc((PVOID)arg);
37
38//only for blocking hooks (currently not implemented
39//// if(pThreadParm->request == ASYNC_BLOCKHOOK)
40//// WSASetBlocking(FALSE, pThreadParm->hThread);
41
42 pThreadParm->fActive = FALSE;
43 RemoveFromQueue(pThreadParm);
44 free((PVOID)pThreadParm);
45
46 DosExit(EXIT_THREAD, 0);
47}
48//******************************************************************************
49//******************************************************************************
50ULONG QueueAsyncJob(ASYNCTHREADPROC asyncproc, PASYNCTHREADPARM pThreadParm, BOOL fSetBlocking)
51{
52 APIRET rc;
53 TID tid;
54
55 pThreadParm->asyncProc = asyncproc;
56 pThreadParm->fActive = TRUE;
57 pThreadParm->fCancelled = FALSE;
58 pThreadParm->next = NULL;
59 pThreadParm->hAsyncTaskHandle = 0;
60
61 pThreadParm->hThread = GetCurrentThread();
62 AddToQueue(pThreadParm);
63
64 if(fSetBlocking) WSASetBlocking(TRUE);
65
66 rc = DosCreateThread(&tid, AsyncThread, (ULONG)pThreadParm, CREATE_READY, 16384);
67 if(rc)
68 {
69 dprintf(("QueueAsyncJob: DosCreateThread failed with error %x", rc));
70 if(fSetBlocking) WSASetBlocking(FALSE);
71 RemoveFromQueue(pThreadParm);
72 WSASetLastError(WSAEFAULT);
73 return 0;
74 }
75 pThreadParm->hAsyncTaskHandle = tid;
76 WSASetLastError(NO_ERROR);
77 return pThreadParm->hAsyncTaskHandle;
78}
79//******************************************************************************
80//******************************************************************************
81void AddToQueue(PASYNCTHREADPARM pThreadParm)
82{
83 asyncThreadMutex.enter();
84 pThreadParm->next = threadList;
85 threadList = pThreadParm;
86 asyncThreadMutex.leave();
87}
88//******************************************************************************
89//******************************************************************************
90void RemoveFromQueue(PASYNCTHREADPARM pThreadParm)
91{
92 PASYNCTHREADPARM pThreadInfo;
93
94 asyncThreadMutex.enter();
95 pThreadInfo = threadList;
96
97 if(pThreadInfo == pThreadParm) {
98 threadList = pThreadParm->next;
99 }
100 else {
101 while(pThreadInfo->next) {
102 if(pThreadInfo->next == pThreadParm) {
103 pThreadInfo->next = pThreadParm->next;
104 break;
105 }
106 pThreadInfo = pThreadInfo->next;
107 }
108 if(pThreadInfo == NULL) {
109 dprintf(("RemoveFromQueue: parm %x not found!!", pThreadParm));
110 DebugInt3();
111 }
112 }
113 memset(pThreadParm, 0, sizeof(*pThreadParm));
114 asyncThreadMutex.leave();
115}
116//******************************************************************************
117//******************************************************************************
118int WIN32API WSACancelAsyncRequest(LHANDLE hAsyncTaskHandle)
119{
120 PASYNCTHREADPARM pThreadInfo;
121 BOOL found = FALSE;
122
123 dprintf(("WSACancelAsyncRequest: cancel task %x", hAsyncTaskHandle));
124 asyncThreadMutex.enter();
125 pThreadInfo = threadList;
126
127 while(pThreadInfo) {
128 if(pThreadInfo->hAsyncTaskHandle == hAsyncTaskHandle) {
129 pThreadInfo->fCancelled = TRUE;
130 found = TRUE;
131 break;
132 }
133 pThreadInfo = pThreadInfo->next;
134 }
135 asyncThreadMutex.leave();
136 if(found == FALSE) {
137 WSASetLastError(WSAEINVAL);
138 dprintf(("WSACancelAsyncRequest: task not found!!"));
139 }
140 return (found) ? NO_ERROR : SOCKET_ERROR;
141}
142//******************************************************************************
143//Only to cancel blocking hooks
144//******************************************************************************
145int WIN32API WSACancelBlockingCall()
146{
147 HANDLE hThread = GetCurrentThread();
148
149 dprintf(("WSACancelBlockingCall"));
150#if 0
151 asyncThreadMutex.enter();
152 pThreadInfo = threadList;
153
154 while(pThreadInfo) {
155 if(pThreadInfo->hThread == hThread) {
156 pThreadInfo->fCancelled = TRUE;
157
158 if(pThreadInfo->request == ASYNC_BLOCKHOOK) {
159 ret = so_cancel(pThreadInfo->blockedsocket);
160 }
161
162 found = TRUE;
163 break;
164 }
165 pThreadInfo = pThreadInfo->next;
166 }
167 asyncThreadMutex.leave();
168#endif
169 return SOCKET_ERROR;
170}
171//******************************************************************************
172//Assumes caller owns async thread mutex!
173//******************************************************************************
174static PASYNCTHREADPARM FindAsyncEvent(SOCKET s)
175{
176 PASYNCTHREADPARM pThreadInfo;
177
178 pThreadInfo = threadList;
179 while(pThreadInfo) {
180 if(pThreadInfo->u.asyncselect.s == s) {
181 return pThreadInfo;
182 }
183 pThreadInfo = pThreadInfo->next;
184 }
185 return NULL;
186}
187//******************************************************************************
188//******************************************************************************
189BOOL FindAndSetAsyncEvent(SOCKET s, HWND hwnd, int msg, ULONG lEvent)
190{
191 PASYNCTHREADPARM pThreadInfo;
192
193 asyncThreadMutex.enter();
194 pThreadInfo = FindAsyncEvent(s);
195 if(pThreadInfo) {
196 pThreadInfo->u.asyncselect.lEvents = lEvent;
197 pThreadInfo->hwnd = hwnd;
198 pThreadInfo->msg = msg;
199 //cancel pending select in async select thread (if any)
200 so_cancel(s);
201
202 //unblock async thread if it was waiting
203 pThreadInfo->u.asyncselect.asyncSem->post();
204 }
205 asyncThreadMutex.leave();
206 return(pThreadInfo != NULL);
207}
208//******************************************************************************
209//******************************************************************************
210void EnableAsyncEvent(SOCKET s, ULONG flags)
211{
212 PASYNCTHREADPARM pThreadInfo;
213
214 asyncThreadMutex.enter();
215 pThreadInfo = FindAsyncEvent(s);
216 if(pThreadInfo) {
217 pThreadInfo->u.asyncselect.lEventsPending |= (pThreadInfo->u.asyncselect.lEvents & flags);
218 //cancel pending select in async select thread (if any)
219 so_cancel(s);
220
221 //unblock async thread if it was waiting
222 pThreadInfo->u.asyncselect.asyncSem->post();
223 }
224 asyncThreadMutex.leave();
225}
226//******************************************************************************
227//******************************************************************************
228BOOL QueryAsyncEvent(SOCKET s, HWND *pHwnd, int *pMsg, ULONG *plEvent)
229{
230 PASYNCTHREADPARM pThreadInfo;
231
232 asyncThreadMutex.enter();
233 pThreadInfo = FindAsyncEvent(s);
234 if(pThreadInfo) {
235 *pHwnd = pThreadInfo->hwnd;
236 *pMsg = pThreadInfo->msg;
237 *plEvent = pThreadInfo->u.asyncselect.lEvents;
238 }
239 asyncThreadMutex.leave();
240 return(pThreadInfo != NULL);
241}
242//******************************************************************************
243//******************************************************************************
Note: See TracBrowser for help on using the repository browser.