Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

162 lines
6.4 KiB

//================================================================================
// Microsoft Confidential
// Copyright (C) Microsoft 1997
//
// Author: RameshV
//================================================================================
//================================================================================
// Required Headers
//================================================================================
#include <adt.h>
//================================================================================
// Definitions of the functions.
//================================================================================
DWORD // Win32 Errors
InitializeProducerConsumer( // Initialize the pointer
OUT PPRODCONS Synch, // The memory must be pre-allocated
IN DWORD MaxProducers, // Total # of simultaneous producers
IN DWORD MaxConsumers // Totat # of consumers
) {
Synch->ProducerSemaphore = Synch->ConsumerSemaphore = NULL;
Synch->ProducerSemaphore = CreateSemaphore(
(LPSECURITY_ATTRIBUTES)NULL, // No security here
MaxProducers, // Initial allowed # of producers
MaxProducers, // Max allowed at any time
NULL // Unnamed
);
if( NULL == Synch->ProducerSemaphore ) return GetLastError();
Synch->ConsumerSemaphore = CreateSemaphore(
(LPSECURITY_ATTRIBUTES)NULL, // No security here
0, // Initial allowed # of consumers
MaxConsumers, // Max allowed at any time
NULL // Unnamed
);
if( NULL == Synch->ConsumerSemaphore ) return GetLastError();
Synch->MaxProducers = MaxProducers;
Synch->MaxConsumers = MaxConsumers;
return ERROR_SUCCESS;
}
VOID
DestroyProducerConsumer( // Destroy and free up resources
IN PPRODCONS Synch // The producer consumer object
) {
if(Synch->ProducerSemaphore) CloseHandle(Synch->ProducerSemaphore);
if(Synch->ConsumerSemaphore) CloseHandle(Synch->ConsumerSemaphore);
}
//================================================================================
// StartProducerEx is expected to be called before trying to "produce" an
// element. If a timeout is specified, then the timeout will act like the
// same as in WaitForSingleObjectEx. Also, if the Alertable flag is on, the
// wait is altertable. The same thing with StartConsumerEx.
//================================================================================
DWORD static _inline // Win32 errors
StartProdConsExInternal( // Gen. fn to enter prod/cons code (internal)
IN PPRODCONS Synch, // Synchronization object
IN DWORD TimeOutMilliSec,// Timeout in milliseconds; 0 ==> polling
IN BOOL Alertable, // Is the wait alertable?
IN BOOL Producer // Is this call from a producer or consumer?
) {
DWORD Status;
Status = WaitForSingleObjectEx(
Producer? Synch->ProducerSemaphore : Synch->ConsumerSemaphore,
TimeOutMilliSec,
Alertable
);
return Status;
}
DWORD static _inline // Win32 errors
EndProdConsExInternal( // Gen. fn to leave prod/cons code(internal)
IN PPRODCONS Synch, // Synchronization object
IN BOOL Producer // Is this call from a producer or consumer?
) {
BOOL Status;
Status = ReleaseSemaphore(
Producer? Synch->ConsumerSemaphore : Synch->ProducerSemaphore,
1, // Release one producer/consumer
NULL // Dont care about how many are still out there
);
if( FALSE == Status ) return GetLastError();
return ERROR_SUCCESS;
}
//================================================================================
// The exported versions are below. The Ex functions allow specification of
// TimeOut and if the wait is alertable. The non-Ex functions have the timeout
// as INFINITE and Alertable as FALSE by default.
//================================================================================
DWORD // Win32 errors
StartProducerEx( // See StartProdConsExInternal
IN PPRODCONS Synch, // Syncho. object
IN DWORD TimeOutMilliSec,// Timeout for wait in milliseconds
IN BOOL Alertable // Is the wait alertable?
) {
return StartProdConsExInternal(Synch,TimeOutMilliSec,Alertable,TRUE);
}
DWORD // Win32 errors
StartConsumerEx( // See StartProdConsExInternal
IN PPRODCONS Synch, // Syncho. object
IN DWORD TimeOutMilliSec,// Timeout for wait in milliseconds
IN BOOL Alertable // Is the wait alertable?
) {
return StartProdConsExInternal(Synch,TimeOutMilliSec,Alertable,FALSE);
}
// These are usual versions. Return value is success if we entered.
// Alertable wait by default, timeout = infinite. So, can return
// WAIT_IO_COMPLETION on success.
DWORD // Win32 errors
StartProducer( // Wait until a producer can start
IN PPRODCONS Synch // The synch object
) {
DWORD Status = StartProducerEx(Synch, INFINITE, FALSE);
if( WAIT_OBJECT_0 == Status ) return ERROR_SUCCESS;
return Status;
}
DWORD // Win32 errors
StartConsumer( // Wait until a consumer can start
IN PPRODCONS Synch // The synch object
) {
DWORD Status = StartConsumerEx(Synch, INFINITE, FALSE);
if( WAIT_OBJECT_0 == Status ) return ERROR_SUCCESS;
return Status;
}
DWORD // Win32 Errors
EndProducer( // See EndProdConsExInternal
IN PPRODCONS Synch // Synch object
) {
return EndProdConsExInternal(Synch, TRUE);
}
DWORD // Win32 errors
EndConsumer( // See EndProdConsExInternal
IN PPRODCONS Synch // Synch object
) {
return EndProdConsExInternal(Synch, TRUE);
}
//================================================================================
// End of file
//================================================================================