00001
00002
00003 #include "pch.h"
00004 #include "wait.h"
00005 #include "misc.h"
00006
00007 #ifdef SOCKETS_AVAILABLE
00008
00009 #ifdef USE_BERKELEY_STYLE_SOCKETS
00010 #include <errno.h>
00011 #include <sys/types.h>
00012 #include <sys/time.h>
00013 #include <unistd.h>
00014 #endif
00015
00016 NAMESPACE_BEGIN(CryptoPP)
00017
00018 WaitObjectContainer::WaitObjectContainer()
00019 {
00020 Clear();
00021 }
00022
00023 void WaitObjectContainer::Clear()
00024 {
00025 #ifdef USE_WINDOWS_STYLE_SOCKETS
00026 m_handles.clear();
00027 #else
00028 m_maxFd = 0;
00029 FD_ZERO(&m_readfds);
00030 FD_ZERO(&m_writefds);
00031 #endif
00032 m_noWait = false;
00033 }
00034
00035 #ifdef USE_WINDOWS_STYLE_SOCKETS
00036
00037 void WaitObjectContainer::AddHandle(HANDLE handle)
00038 {
00039 m_handles.push_back(handle);
00040 }
00041
00042 bool WaitObjectContainer::Wait(unsigned long milliseconds)
00043 {
00044 if (m_noWait || m_handles.empty())
00045 return true;
00046
00047 DWORD result = ::WaitForMultipleObjects(m_handles.size(), &m_handles[0], FALSE, milliseconds);
00048
00049 if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + m_handles.size())
00050 return true;
00051 else if (result == WAIT_TIMEOUT)
00052 return false;
00053 else
00054 throw Err("WaitObjectContainer: WaitForMultipleObjects failed with error " + IntToString(::GetLastError()));
00055 }
00056
00057 #else
00058
00059 void WaitObjectContainer::AddReadFd(int fd)
00060 {
00061 FD_SET(fd, &m_readfds);
00062 m_maxFd = STDMAX(m_maxFd, fd);
00063 }
00064
00065 void WaitObjectContainer::AddWriteFd(int fd)
00066 {
00067 FD_SET(fd, &m_writefds);
00068 m_maxFd = STDMAX(m_maxFd, fd);
00069 }
00070
00071 bool WaitObjectContainer::Wait(unsigned long milliseconds)
00072 {
00073 if (m_noWait || m_maxFd == 0)
00074 return true;
00075
00076 timeval tv, *timeout;
00077
00078 if (milliseconds == INFINITE_TIME)
00079 timeout = NULL;
00080 else
00081 {
00082 tv.tv_sec = milliseconds / 1000;
00083 tv.tv_usec = (milliseconds % 1000) * 1000;
00084 timeout = &tv;
00085 }
00086
00087 int result = select(m_maxFd+1, &m_readfds, &m_writefds, NULL, timeout);
00088
00089 if (result > 0)
00090 return true;
00091 else if (result == 0)
00092 return false;
00093 else
00094 throw Err("WaitObjectContainer: select failed with error " + errno);
00095 }
00096
00097 #endif
00098
00099
00100
00101 bool Waitable::Wait(unsigned long milliseconds)
00102 {
00103 WaitObjectContainer container;
00104 GetWaitObjects(container);
00105 return container.Wait(milliseconds);
00106 }
00107
00108 NAMESPACE_END
00109
00110 #endif