Changeset 44 for trunk/src/helpers/threads.c
- Timestamp:
- Mar 8, 2001, 8:28:45 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/threads.c
r38 r44 50 50 #include "setup.h" // code generation and debugging options 51 51 52 #include "helpers\linklist.h" 52 53 #include "helpers\threads.h" 53 54 … … 58 59 * see threads.c. 59 60 */ 61 62 /* ****************************************************************** 63 * 64 * Global variables 65 * 66 ********************************************************************/ 67 68 LINKLIST G_llThreadInfos; 69 // linked list of all THREADINFOS ever created... 70 // no auto-free 71 HMTX G_hmtxThreadInfos = NULLHANDLE; 72 73 /* ****************************************************************** 74 * 75 * Functions 76 * 77 ********************************************************************/ 78 79 /* 80 *@@ LockThreadInfos: 81 * 82 *@@added V0.9.9 (2001-03-07) [umoeller] 83 */ 84 85 BOOL LockThreadInfos(VOID) 86 { 87 APIRET arc = NO_ERROR; 88 89 if (G_hmtxThreadInfos == NULLHANDLE) 90 { 91 // first call: 92 arc = DosCreateMutexSem(NULL, // unnamed 93 &G_hmtxThreadInfos, 94 0, // unshared 95 TRUE); // request! 96 lstInit(&G_llThreadInfos, FALSE); 97 } 98 else 99 { 100 arc = DosRequestMutexSem(G_hmtxThreadInfos, 101 SEM_INDEFINITE_WAIT); 102 } 103 104 return (arc == NO_ERROR); 105 } 106 107 /* 108 *@@ UnlockThreadInfos: 109 * 110 *@@added V0.9.9 (2001-03-07) [umoeller] 111 */ 112 113 VOID UnlockThreadInfos(VOID) 114 { 115 DosReleaseMutexSem(G_hmtxThreadInfos); 116 } 60 117 61 118 /* … … 108 165 DosCloseEventSem(pti->hevRunning); 109 166 167 // V0.9.9 (2001-03-07) [umoeller] 168 // remove thread from global list 169 if (LockThreadInfos()) 170 { 171 lstRemoveItem(&G_llThreadInfos, pti); 172 UnlockThreadInfos(); 173 } 174 110 175 // (2000-12-18) [lafaix] clean up pti if thread is transient. 111 176 if (pti->flFlags & THRF_TRANSIENT) … … 128 193 /* 129 194 *@@ thrCreate: 130 * this function fills a THREADINFO structure in *pti131 * a nd starts anew thread using _beginthread.195 * this function fills a THREADINFO structure and starts 196 * a new thread using _beginthread. 132 197 * 133 198 * You must pass the thread function in pfn, which will … … 144 209 * function is prototyped somewhere, VAC will automatically 145 210 * modify the function's linkage, and you'll run into 146 * compiler warnings. 147 * 148 * ptiMyself is then a pointer to the THREADINFO structure. 211 * crashes. 212 * 213 * The thread's ptiMyself is then a pointer to the 214 * THREADINFO structure passed to this function. 149 215 * ulData may be obtained like this: 150 + ULONG ulData = ((PTHREADINFO)ptiMyself)->ulData; 216 * 217 + ULONG ulData = ptiMyself->ulData; 218 * 219 * The THREADINFO structure passed to this function must 220 * be accessible all the time while the thread is running 221 * because the thr* functions will use it for maintenance. 222 * 223 * This function does NOT check whether a thread is 224 * already running in *pti. Do not use the same THREADINFO 225 * for several threads. 226 * 227 * If you do not want to manage the structure yourself, 228 * you can pass the THRF_TRANSIENT flag (see below). 151 229 * 152 230 * thrCreate does not call your thread func directly, … … 156 234 * explicitly, because this would skip the exit processing 157 235 * (cleanup) in thr_fntGeneric. Instead, just fall out of 158 * your thread function. 159 * 160 * This function does NOT check whether a thread is 161 * already running in *pti. If it is, that information 162 * will be lost. 236 * your thread function, or return(). 163 237 * 164 238 * flFlags can be any combination of the following: … … 194 268 *@@changed V0.9.7 (2000-12-18) [lafaix]: THRF_TRANSIENT support added 195 269 *@@changed V0.9.9 (2001-02-06) [umoeller]: now returning TID 270 *@@changed V0.9.9 (2001-03-07) [umoeller]: added pcszThreadName 196 271 */ 197 272 … … 200 275 PBOOL pfRunning, // out: variable set to TRUE while thread is running; 201 276 // ptr can be NULL 277 const char *pcszThreadName, // in: thread name (for identification) 202 278 ULONG flFlags, // in: THRF_* flags 203 279 ULONG ulData) // in: user data to be stored in THREADINFO … … 209 285 { 210 286 if (pti == NULL) 211 pti = (PTHREADINFO) malloc(sizeof(THREADINFO)); 287 pti = (PTHREADINFO)malloc(sizeof(THREADINFO)); 288 // cleaned up by thr_fntGeneric on exit 212 289 } 213 290 214 291 if (pti) 215 292 { 216 // we arrive here if *ppti was NULL or (*ppti->tid == NULLHANDLE),217 // i.e. the thread is not already running.218 // _beginthread is contained both in the VAC++ and EMX219 // C libraries with this syntax.220 293 memset(pti, 0, sizeof(THREADINFO)); 221 294 pti->cbStruct = sizeof(THREADINFO); 222 295 pti->pThreadFunc = (PVOID)pfn; 223 296 pti->pfRunning = pfRunning; 297 pti->pcszThreadName = pcszThreadName; // V0.9.9 (2001-03-07) [umoeller] 224 298 pti->flFlags = flFlags; 225 299 pti->ulData = ulData; … … 251 325 252 326 if (ulrc) 327 { 328 if (LockThreadInfos()) 329 { 330 lstAppendItem(&G_llThreadInfos, pti); 331 UnlockThreadInfos(); 332 } 333 253 334 if (flFlags & THRF_WAIT) 254 335 { … … 258 339 SEM_INDEFINITE_WAIT); 259 340 } 341 } 260 342 } 261 343 } … … 281 363 * 282 364 *@@added V0.9.5 (2000-08-26) [umoeller] 365 *@@changed V0.9.9 (2001-03-07) [umoeller]: added pcszThreadName 283 366 */ 284 367 285 368 ULONG thrRunSync(HAB hab, // in: anchor block of calling thread 286 PTHREADFUNC pfn, // in: thread function 287 ULONG ulData) // in: data for thread function 369 PTHREADFUNC pfn, // in: passed to thrCreate 370 const char *pcszThreadName, // in: passed to thrCreate 371 ULONG ulData) // in: passed to thrCreate 288 372 { 289 373 ULONG ulrc = 0; … … 306 390 pfn, 307 391 NULL, 392 pcszThreadName, 308 393 THRF_PMMSGQUEUE, 309 394 ulData); … … 336 421 337 422 return (ulrc); 423 } 424 425 /* 426 *@@ thrListThreads: 427 * returns an array of THREADINFO structures 428 * for all threads that have been started using 429 * thrCreate (or thrRunSync). 430 * 431 * If no threads are running yet, this returns 432 * NULL. 433 * 434 * Otherwise, this returns the pointer to the 435 * first array item, and *pcThreads receives 436 * the array item count (NOT the total array 437 * size). The array is a copied snapshot of all 438 * current THREADINFO's and must be free()'d 439 * by the caller. 440 * 441 *@@added V0.9.9 (2001-03-07) [umoeller] 442 */ 443 444 PTHREADINFO thrListThreads(PULONG pcThreads) 445 { 446 PTHREADINFO pArray = 0; 447 448 if (LockThreadInfos()) 449 { 450 PTHREADINFO pThis; 451 PLISTNODE pNode; 452 *pcThreads = lstCountItems(&G_llThreadInfos); 453 _Pmpf((__FUNCTION__ ": got %d threads", *pcThreads)); 454 pArray = (PTHREADINFO)malloc(*pcThreads * sizeof(THREADINFO)); 455 pThis = pArray; 456 457 pNode = lstQueryFirstNode(&G_llThreadInfos); 458 while (pNode) 459 { 460 memcpy(pThis, 461 (PTHREADINFO)pNode->pItemData, 462 sizeof(THREADINFO)); 463 pThis++; 464 pNode = pNode->pNext; 465 } 466 467 UnlockThreadInfos(); 468 } 469 470 return (pArray); 471 } 472 473 /* 474 *@@ thrFindThread: 475 * attempts to find the thread with the specified 476 * TID; if found, returns TRUE and copies its 477 * THREADINFO into *pti. 478 * 479 *@@added V0.9.9 (2001-03-07) [umoeller] 480 */ 481 482 BOOL thrFindThread(PTHREADINFO pti, 483 ULONG tid) 484 { 485 BOOL brc = FALSE; 486 if (LockThreadInfos()) 487 { 488 PLISTNODE pNode = lstQueryFirstNode(&G_llThreadInfos); 489 while (pNode) 490 { 491 PTHREADINFO ptiThis = (PTHREADINFO)pNode->pItemData; 492 if (ptiThis->tid == tid) 493 { 494 memcpy(pti, ptiThis, sizeof(THREADINFO)); 495 brc = TRUE; 496 break; 497 } 498 pNode = pNode->pNext; 499 } 500 501 UnlockThreadInfos(); 502 } 503 504 return (brc); 338 505 } 339 506
Note:
See TracChangeset
for help on using the changeset viewer.