Repository: dotnet/runtime
File: src/coreclr/nativeaot/Runtime/threadstore.cpp (C++)

Code before:
    PalAttachThread(pAttachingThread);

    //
    // Init the thread buffer
    //
    pAttachingThread->Construct();
    ASSERT(pAttachingThread->m_ThreadStateFlags == Thread::TSF_Unknown);

    // fAcquireThreadStoreLock is false when threads are created/attached for GC purpose
    // in such case the lock is already held and GC takes care to ensure safe access to the threadstore

    ThreadStore* pTS = GetThreadStore();
    CrstHolderWithState threadStoreLock(&pTS->m_Lock, fAcquireThreadStoreLock);

    //
    // Set thread state to be attached
    //
    ASSERT(pAttachingThread->m_ThreadStateFlags == Thread::TSF_Unknown);
    pAttachingThread->m_ThreadStateFlags = Thread::TSF_Attached;

    pTS->m_ThreadList.PushHead(pAttachingThread);

#if defined(TARGET_UNIX) && !defined(TARGET_WASM)
    if (!InsertThreadIntoAsyncSafeMap(pAttachingThread->m_threadId, pAttachingThread))
    {
        ASSERT_UNCONDITIONALLY("Failed to insert thread into async-safe map due to OOM.");
        RhFailFast();
    }
#endif // TARGET_UNIX && !TARGET_WASM
}

// static
void ThreadStore::AttachCurrentThread()
{
    AttachCurrentThread(true);
}

void ThreadStore::DetachCurrentThread()
{
    // The thread may not have been initialized because it may never have run managed code before.
    Thread * pDetachingThread = RawGetCurrentThread();

    // The thread was not initialized yet, so it was not attached
    if (!pDetachingThread->IsInitialized())
    {
        return;
    }

    // detach callback should not call us twice
    ASSERT(!pDetachingThread->IsDetached());


Review comment (bug):
```suggestion
        PalPrintFatalError("\nFailed to insert thread into async-safe map due to out of memory.\n");
```

Code after:
    PalAttachThread(pAttachingThread);

    //
    // Init the thread buffer
    //
    pAttachingThread->Construct();
    ASSERT(pAttachingThread->m_ThreadStateFlags == Thread::TSF_Unknown);

    // fAcquireThreadStoreLock is false when threads are created/attached for GC purpose
    // in such case the lock is already held and GC takes care to ensure safe access to the threadstore

    ThreadStore* pTS = GetThreadStore();
    CrstHolderWithState threadStoreLock(&pTS->m_Lock, fAcquireThreadStoreLock);

    //
    // Set thread state to be attached
    //
    ASSERT(pAttachingThread->m_ThreadStateFlags == Thread::TSF_Unknown);
    pAttachingThread->m_ThreadStateFlags = Thread::TSF_Attached;

    pTS->m_ThreadList.PushHead(pAttachingThread);

#if defined(TARGET_UNIX) && !defined(TARGET_WASM)
    if (!InsertThreadIntoAsyncSafeMap(pAttachingThread->m_threadId, pAttachingThread))
    {
        PalPrintFatalError("\nFailed to insert thread into async-safe map due to out of memory.\n");
        RhFailFast();
    }
#endif // TARGET_UNIX && !TARGET_WASM
}

// static
void ThreadStore::AttachCurrentThread()
{
    AttachCurrentThread(true);
}

void ThreadStore::DetachCurrentThread()
{
    // The thread may not have been initialized because it may never have run managed code before.
    Thread * pDetachingThread = RawGetCurrentThread();

    // The thread was not initialized yet, so it was not attached
    if (!pDetachingThread->IsInitialized())
    {
        return;
    }

    // detach callback should not call us twice
    ASSERT(!pDetachingThread->IsDetached());