| | 579 | |
| | 580 | /** |
| | 581 | * Child fork callback for ressetting gPreAllocThrd (normally used for |
| | 582 | * thread 1) and other global thread data variables to their initial state. |
| | 583 | * |
| | 584 | * @note This callback must be registered with a priority higher than |
| | 585 | * fhForkChild1 and any other callback that might call LIBC thread functions. |
| | 586 | * |
| | 587 | * @returns 0 on success. |
| | 588 | * @returns -errno on failure. |
| | 589 | * @param pForkHandle Pointer to fork handle. |
| | 590 | * @param enmOperation Fork operation. |
| | 591 | */ |
| | 592 | static int threadForkChild1(__LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation) |
| | 593 | { |
| | 594 | LIBCLOG_ENTER("pForkHandle=%p enmOperation=%d\n", (void *)pForkHandle, enmOperation); |
| | 595 | |
| | 596 | if (enmOperation != __LIBC_FORK_OP_FORK_CHILD) |
| | 597 | LIBCLOG_RETURN_INT(0); |
| | 598 | |
| | 599 | /* |
| | 600 | * Release the mutex locked in parent. Note that we do it here rather than |
| | 601 | * in threadForkCompletion as that one called too late and this mutex |
| | 602 | * can be used earlier (e.g. when accessing LIBC thread data). |
| | 603 | */ |
| | 604 | _fmutex_release_fork(&gmtxThrdDB); |
| | 605 | |
| | 606 | /* |
| | 607 | * Reset other global thread variables. |
| | 608 | */ |
| | 609 | gpThrdDB = NULL; |
| | 610 | gcThrdDBEntries = 0; |
| | 611 | gpThrdDBZombies = NULL; |
| | 612 | gcThrdDBZombies = 0; |
| | 613 | gpTermHead = NULL; |
| | 614 | gpTermTail = NULL; |
| | 615 | gsmtxTerm = '\0'; |
| | 616 | |
| | 617 | /* |
| | 618 | * Cause the main thread to be re-iniitialized as new. |
| | 619 | */ |
| | 620 | gfPreAllocThrd = 0; |
| | 621 | *__libc_gpTLS = NULL; |
| | 622 | __libc_threadCurrentSlow(); |
| | 623 | |
| | 624 | LIBCLOG_RETURN_INT(0); |
| | 625 | } |
| | 626 | |
| | 627 | |
| | 628 | _FORK_CHILD1(0xffffff02, threadForkChild1) |