// Copyright (c) 2007, Monju System Architects
//
// Released under the Monju-Public copyright license:
//
// Permission is hereby granted, free of charge, to any person or entity
// obtaining a copy of this software and associated documentation files
// (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies and modifications
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of published, sold, or
// ownership-transferred versions of the Software. The notices are not
// required for binary-only releases or binary-only derivatives of the
// Software, or documentation provided with binary-only releases and
// binary-only derivatives.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// NOTE: Unix only.
#ifndef _WIN32
// INCLUDES.
#include <stdlib.h>
#include <sys/select.h>
#include "public/signal.h"
#include "public/waitForDescriptor.h"
// EXTERNAL VARIABLES.
extern SIGNAL_TYPE g_shouldExitSignal;
// waitUntilReadable()
//
// Given a file descriptor, will wait the given amount of time (or forever if the time is
// less than zero) for the file descriptor to be readable. Returns false if the
// wait times out or if the system is exiting.
bool waitUntilReadable(int fileDescriptor) {
return waitUntilReadable(fileDescriptor, NULL, -1, 0);
}
bool waitUntilReadable(int fileDescriptor, double timeout, bool* pTimedOut) {
return waitUntilReadable(fileDescriptor, (int) timeout, (int) (timeout * 1000000.0), pTimedOut);
}
bool waitUntilReadable(int fileDescriptor, int timeoutSeconds, bool* pTimedOut) {
return waitUntilReadable(fileDescriptor, timeoutSeconds, 0, pTimedOut);
}
bool waitUntilReadable(int fileDescriptor, int timeoutSeconds, int timeoutMicroseconds, bool* pTimedOut) {
fd_set readFileDescriptors;
// ADD THE GIVEN AND THE SHOULD-EXIT DESCRIPTORS TO OUR LIST.
FD_ZERO(&readFileDescriptors);
FD_SET(fileDescriptor, &readFileDescriptors);
FD_SET(g_shouldExitSignal.m_pipe[0], &readFileDescriptors);
// WAIT FOR EITHER DESCRIPTOR, HANDLE TIMEOUT AS APPROPRIATE.
if (timeoutSeconds < 0) {
select(2, &readFileDescriptors, NULL, NULL, NULL);
}
else {
struct timeval timeValue;
int count = 0;
timeValue.tv_sec = timeoutSeconds;
timeValue.tv_usec = timeoutMicroseconds;
count = select(2, &readFileDescriptors, NULL, NULL, &timeValue);
if (count == 0) {
if (pTimedOut != NULL) {
*pTimedOut = true;
}
return false;
}
}
// IF THE PASSED IN DESCRIPTOR IS READABLE, RETURN 'true'.
if (FD_ISSET(fileDescriptor, &readFileDescriptors)) {
return true;
}
return false;
}
// waitUntilWriteable()
//
// Given a file descriptor, will wait the given amount of time (or forever if the time is
// less than zero) for the file descriptor to be writeable. Returns false if the
// wait times out or if the system is exiting.
bool waitUntilWriteable(int fileDescriptor) {
return waitUntilWriteable(fileDescriptor, NULL, -1, 0);
}
bool waitUntilWriteable(int fileDescriptor, double timeout, bool* pTimedOut) {
return waitUntilWriteable(fileDescriptor, (int) timeout, (int) (timeout * 1000000.0), pTimedOut);
}
bool waitUntilWriteable(int fileDescriptor, int timeoutSeconds, bool* pTimedOut) {
return waitUntilWriteable(fileDescriptor, timeoutSeconds, 0, pTimedOut);
}
bool waitUntilWriteable(int fileDescriptor, int timeoutSeconds, int timeoutMicroseconds, bool* pTimedOut) {
fd_set readFileDescriptors;
fd_set writeFileDescriptors;
// ADD THE GIVEN FILE DESCRIPTOR TO THE WRITE LIST.
FD_ZERO(&writeFileDescriptors);
FD_SET(fileDescriptor, &writeFileDescriptors);
// ADD THE SHOULD-EXIT DESCRIPTORS TO THE READ LIST.
FD_ZERO(&readFileDescriptors);
FD_SET(g_shouldExitSignal.m_pipe[0], &readFileDescriptors);
// WAIT FOR EITHER DESCRIPTOR, HANDLE TIMEOUT AS APPROPRIATE.
if (timeoutSeconds < 0) {
select(2, &readFileDescriptors, &writeFileDescriptors, NULL, NULL);
}
else {
struct timeval timeValue;
int count = 0;
timeValue.tv_sec = timeoutSeconds;
timeValue.tv_usec = timeoutMicroseconds;
count = select(2, &readFileDescriptors, &writeFileDescriptors, NULL, &timeValue);
if (count == 0) {
if (pTimedOut != NULL) {
*pTimedOut = true;
}
return false;
}
}
// IF THE PASSED IN DESCRIPTOR IS WRITABLE, RETURN 'true'.
if (FD_ISSET(fileDescriptor, &writeFileDescriptors)) {
return true;
}
return false;
}
#endif // #ifndef _WIN32
|