WSL/test/linux/unit_tests/lxtevent.c

270 lines
5.8 KiB
C
Raw Permalink Normal View History

/*++
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;
}