Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An improper locking bug on the lock NewThread->StartMutex #167

Open
ryancaicse opened this issue Sep 18, 2021 · 4 comments
Open

An improper locking bug on the lock NewThread->StartMutex #167

ryancaicse opened this issue Sep 18, 2021 · 4 comments

Comments

@ryancaicse
Copy link

Hi, developers, thank you for your checking. It seems the lock NewThread->StartMutex is not released correctly when !KSUCCESS(KernelStatus)?

pthread_mutex_lock(&(NewThread->StartMutex));
//
// Block all possible signals in the new thread while it sets itself up,
// including the internal signals.
//
FILL_SIGNAL_SET(InternalSignals);
NewThread->SignalMask = OsSetSignalBehavior(SignalMaskBlocked,
SignalMaskOperationOverwrite,
&InternalSignals);
KernelStatus = OsCreateThread(NULL,
0,
ClpThreadStart,
NewThread,
NewThread->Attribute.StackBase,
NewThread->Attribute.StackSize,
NewThread->OsData,
&(NewThread->ThreadId));
OsSetSignalBehavior(SignalMaskBlocked,
SignalMaskOperationOverwrite,
&(NewThread->SignalMask));
if (!KSUCCESS(KernelStatus)) {
Status = ClConvertKstatusToErrorNumber(KernelStatus);
ClpDestroyThreadKeyData(NewThread);
ClpDestroyThread(NewThread);
return Status;
}

@evangreen
Copy link
Collaborator

Thanks Ryan! Technically you're right, things would be aesthetically balanced if we had a pthread_mutex_unlock(&(NewThread->StartMutex)) in the !KSUCCESS() case. In practice it doesn't end up mattering because NewThread is being destroyed in the !KSUCCESS() case, having failed to start the new thread.

I'm tempted to leave things as-is.

@ryancaicse
Copy link
Author

@evangreen Hi, thank you for your reply and confirm this!

There is a similar case, the Thread->StartMutex is not released before the thread goes die. Would it better to release the lock before?

ClCurrentThread = Thread;
pthread_mutex_lock(&(Thread->StartMutex));
OsSetSignalBehavior(SignalMaskBlocked,
SignalMaskOperationOverwrite,
&(Thread->SignalMask));
pthread_testcancel();
Result = Thread->ThreadRoutine(Thread->ThreadParameter);
pthread_exit(Result);
return;

@evangreen
Copy link
Collaborator

Hm. It's a similar story there. The StartMutex acts like a barrier, ensuring that ClpThreadStart() doesn't let the thread run its main routine until pthread_create() has finished initializing the thread members. I suppose the StartMutex could be replaced with a pthread_cond_t, but the mutex is a little lighter.

@ryancaicse
Copy link
Author

@evangreen OK, Thank you. Feel free to close this issue if they would be fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants