mirror of
https://github.com/microsoft/WSL.git
synced 2025-07-03 23:33:21 +00:00

Many Microsoft employees have contributed to the Windows Subsystem for Linux, this commit is the result of their work since 2016. The entire history of the Windows Subsystem for Linux can't be shared here, but here's an overview of WSL's history after it moved to it own repository in 2021: Number of commits on the main branch: 2930 Number of contributors: 31 Head over https://github.com/microsoft/WSL/releases for a more detailed history of the features added to WSL since 2021.
269 lines
5.8 KiB
C
269 lines
5.8 KiB
C
/*++
|
|
|
|
Copyright (c) Microsoft. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
lxtevent.c
|
|
|
|
Abstract:
|
|
|
|
This file contains synchronization event primitive support. It enables
|
|
simple synchronization across threads and forked processes.
|
|
|
|
--*/
|
|
|
|
#include "lxtevent.h"
|
|
#include "lxtlog.h"
|
|
#include <sys/mman.h>
|
|
|
|
int LxtSynchronizationEventClear(PLXT_SYNCHRONIZATION_EVENT Event)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine clears the synchronization event.
|
|
|
|
Arguments:
|
|
|
|
Event - Supplies a pointer to synchronization event.
|
|
|
|
Return Value:
|
|
|
|
0 on success, -1 on failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
int Result = LXT_RESULT_FAILURE;
|
|
|
|
LxtCheckResult(pthread_mutex_lock(&Event->Lock));
|
|
if (Event->Fail != 0)
|
|
{
|
|
LxtCheckResult(pthread_mutex_unlock(&Event->Lock));
|
|
Result = LXT_RESULT_FAILURE;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Event->Ready = 0;
|
|
LxtCheckResult(pthread_mutex_unlock(&Event->Lock));
|
|
|
|
ErrorExit:
|
|
return Result;
|
|
}
|
|
|
|
int LxtSynchronizationEventDestroy(PLXT_SYNCHRONIZATION_EVENT* Event)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine frees all resources allocated for the event.
|
|
|
|
Arguments:
|
|
|
|
Event - Supplies a pointer to synchronization event.
|
|
|
|
Return Value:
|
|
|
|
0 on success, -1 on failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
int Result = LXT_RESULT_FAILURE;
|
|
|
|
LxtCheckResult(pthread_mutex_destroy(&(*Event)->Lock));
|
|
LxtCheckResult(pthread_mutexattr_destroy(&(*Event)->LockAttribute));
|
|
LxtCheckResult(pthread_cond_destroy(&(*Event)->WaitConditionalVariable));
|
|
LxtCheckResult(pthread_condattr_destroy(&(*Event)->ConditionVariableAttribute));
|
|
LxtCheckResult(munmap(*Event, sizeof(*Event)));
|
|
|
|
ErrorExit:
|
|
return Result;
|
|
}
|
|
|
|
int LxtSynchronizationEventFail(PLXT_SYNCHRONIZATION_EVENT Event)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine sets the fail flag and causes blocked event to be woken up and
|
|
return with error and also any further calls to set/wait on the event to
|
|
fail.
|
|
|
|
Arguments:
|
|
|
|
Event - Supplies a pointer to synchronization event.
|
|
|
|
Return Value:
|
|
|
|
0 on success, -1 on failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
int Result = LXT_RESULT_FAILURE;
|
|
|
|
LxtCheckResult(pthread_mutex_lock(&Event->Lock));
|
|
Event->Fail = 1;
|
|
LxtCheckResult(pthread_mutex_unlock(&Event->Lock));
|
|
LxtCheckResult(pthread_cond_signal(&Event->WaitConditionalVariable));
|
|
|
|
ErrorExit:
|
|
return Result;
|
|
}
|
|
|
|
int LxtSynchronizationEventInit(PLXT_SYNCHRONIZATION_EVENT* Event)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine initializes synchronization event.
|
|
|
|
Arguments:
|
|
|
|
Event - Supplies a pointer to where synchronization event will be allocated.
|
|
|
|
Return Value:
|
|
|
|
0 on success, -1 on failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
void* MapResult;
|
|
int Result = LXT_RESULT_FAILURE;
|
|
PLXT_SYNCHRONIZATION_EVENT LocalEvent = NULL;
|
|
|
|
LxtCheckMapErrno(LocalEvent = mmap(NULL, sizeof(*Event), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0));
|
|
|
|
LxtCheckResult(pthread_mutexattr_init(&LocalEvent->LockAttribute));
|
|
LxtCheckResult(pthread_mutexattr_setpshared(&LocalEvent->LockAttribute, PTHREAD_PROCESS_SHARED));
|
|
|
|
LxtCheckResult(pthread_mutex_init(&LocalEvent->Lock, &LocalEvent->LockAttribute));
|
|
LxtCheckResult(pthread_condattr_init(&LocalEvent->ConditionVariableAttribute));
|
|
LxtCheckResult(pthread_condattr_setpshared(&LocalEvent->ConditionVariableAttribute, PTHREAD_PROCESS_SHARED));
|
|
|
|
LxtCheckResult(pthread_cond_init(&LocalEvent->WaitConditionalVariable, &LocalEvent->ConditionVariableAttribute));
|
|
|
|
LocalEvent->Ready = 0;
|
|
LocalEvent->Fail = 0;
|
|
*Event = LocalEvent;
|
|
Result = 0;
|
|
|
|
ErrorExit:
|
|
return Result;
|
|
}
|
|
|
|
int LxtSynchronizationEventReset(PLXT_SYNCHRONIZATION_EVENT Event)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine resets event to the initialized state.
|
|
|
|
Arguments:
|
|
|
|
Event - Supplies a pointer to synchronization event.
|
|
|
|
Return Value:
|
|
|
|
0 on success, -1 on failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
int Result = LXT_RESULT_FAILURE;
|
|
|
|
LxtCheckResult(pthread_mutex_lock(&Event->Lock));
|
|
LxtCheckResult(pthread_cond_init(&Event->WaitConditionalVariable, &Event->ConditionVariableAttribute));
|
|
|
|
Event->Fail == 0;
|
|
Event->Ready = 0;
|
|
LxtCheckResult(pthread_mutex_unlock(&Event->Lock));
|
|
|
|
ErrorExit:
|
|
return Result;
|
|
}
|
|
|
|
int LxtSynchronizationEventSet(PLXT_SYNCHRONIZATION_EVENT Event)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine sets the synchronization event.
|
|
|
|
Arguments:
|
|
|
|
Event - Supplies a pointer to synchronization event.
|
|
|
|
Return Value:
|
|
|
|
0 on success, -1 on failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
int Result = LXT_RESULT_FAILURE;
|
|
|
|
LxtCheckResult(pthread_mutex_lock(&Event->Lock));
|
|
if (Event->Fail != 0)
|
|
{
|
|
LxtCheckResult(pthread_mutex_unlock(&Event->Lock));
|
|
Result = LXT_RESULT_FAILURE;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Event->Ready = 1;
|
|
LxtCheckResult(pthread_mutex_unlock(&Event->Lock));
|
|
LxtCheckResult(pthread_cond_signal(&Event->WaitConditionalVariable));
|
|
|
|
ErrorExit:
|
|
return Result;
|
|
}
|
|
|
|
int LxtSynchronizationEventWait(PLXT_SYNCHRONIZATION_EVENT Event)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine blocks on event until it is signalled.
|
|
|
|
Arguments:
|
|
|
|
Event - Supplies a pointer to synchronization event.
|
|
|
|
Return Value:
|
|
|
|
0 on success, -1 on failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
int Result = LXT_RESULT_FAILURE;
|
|
|
|
LxtCheckResult(pthread_mutex_lock(&Event->Lock));
|
|
while ((Event->Ready == 0) && (Event->Fail == 0))
|
|
{
|
|
LxtCheckResult(pthread_cond_wait(&Event->WaitConditionalVariable, &Event->Lock));
|
|
}
|
|
|
|
if (Event->Fail != 0)
|
|
{
|
|
LxtCheckResult(pthread_mutex_unlock(&Event->Lock));
|
|
Result = LXT_RESULT_FAILURE;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
LxtCheckResult(pthread_mutex_unlock(&Event->Lock));
|
|
|
|
ErrorExit:
|
|
return Result;
|
|
}
|