Common: Port Event class from YBaseLib over

This commit is contained in:
Connor McLaughlin 2020-04-05 22:57:35 +10:00
parent 70ccdcfc30
commit abb87f497f
5 changed files with 174 additions and 0 deletions

View File

@ -19,6 +19,8 @@ add_library(common
cpu_detect.h cpu_detect.h
cubeb_audio_stream.cpp cubeb_audio_stream.cpp
cubeb_audio_stream.h cubeb_audio_stream.h
event.cpp
event.h
fifo_queue.h fifo_queue.h
file_system.cpp file_system.cpp
file_system.h file_system.h

View File

@ -48,6 +48,7 @@
<ClInclude Include="d3d11\staging_texture.h" /> <ClInclude Include="d3d11\staging_texture.h" />
<ClInclude Include="d3d11\stream_buffer.h" /> <ClInclude Include="d3d11\stream_buffer.h" />
<ClInclude Include="d3d11\texture.h" /> <ClInclude Include="d3d11\texture.h" />
<ClInclude Include="event.h" />
<ClInclude Include="fifo_queue.h" /> <ClInclude Include="fifo_queue.h" />
<ClInclude Include="file_system.h" /> <ClInclude Include="file_system.h" />
<ClInclude Include="gl\program.h" /> <ClInclude Include="gl\program.h" />
@ -87,6 +88,7 @@
<ClCompile Include="d3d11\staging_texture.cpp" /> <ClCompile Include="d3d11\staging_texture.cpp" />
<ClCompile Include="d3d11\stream_buffer.cpp" /> <ClCompile Include="d3d11\stream_buffer.cpp" />
<ClCompile Include="d3d11\texture.cpp" /> <ClCompile Include="d3d11\texture.cpp" />
<ClCompile Include="event.cpp" />
<ClCompile Include="file_system.cpp" /> <ClCompile Include="file_system.cpp" />
<ClCompile Include="gl\program.cpp" /> <ClCompile Include="gl\program.cpp" />
<ClCompile Include="gl\shader_cache.cpp" /> <ClCompile Include="gl\shader_cache.cpp" />

View File

@ -56,6 +56,7 @@
<ClInclude Include="gl\shader_cache.h"> <ClInclude Include="gl\shader_cache.h">
<Filter>gl</Filter> <Filter>gl</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="event.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="jit_code_buffer.cpp" /> <ClCompile Include="jit_code_buffer.cpp" />
@ -108,6 +109,7 @@
<ClCompile Include="gl\shader_cache.cpp"> <ClCompile Include="gl\shader_cache.cpp">
<Filter>gl</Filter> <Filter>gl</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="event.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Natvis Include="bitfield.natvis" /> <Natvis Include="bitfield.natvis" />

138
src/common/event.cpp Normal file
View File

@ -0,0 +1,138 @@
#include "event.h"
#include "assert.h"
#if defined(WIN32)
#include <malloc.h>
#include "windows_headers.h"
#elif defined(__linux__) || defined(__APPLE__)
#include <fcntl.h>
#include <poll.h>
#include <unistd.h>
#ifdef __APPLE__
#include <stdlib.h>
#else
#include <malloc.h>
#endif
#endif
namespace Common {
#if defined(WIN32)
Event::Event(bool auto_reset /* = false */)
{
m_event_handle = reinterpret_cast<void*>(CreateEvent(nullptr, auto_reset ? FALSE : TRUE, FALSE, nullptr));
Assert(m_event_handle != nullptr);
}
Event::~Event()
{
CloseHandle(reinterpret_cast<HANDLE>(m_event_handle));
}
void Event::Signal()
{
SetEvent(reinterpret_cast<HANDLE>(m_event_handle));
}
void Event::Wait()
{
WaitForSingleObject(reinterpret_cast<HANDLE>(m_event_handle), INFINITE);
}
bool Event::TryWait(u32 timeout_in_ms)
{
return (WaitForSingleObject(reinterpret_cast<HANDLE>(m_event_handle), timeout_in_ms) == WAIT_OBJECT_0);
}
void Event::Reset()
{
ResetEvent(reinterpret_cast<HANDLE>(m_event_handle));
}
void Event::WaitForMultipleEvents(Event** events, u32 num_events)
{
DebugAssert(num_events > 0);
HANDLE* event_handles = (HANDLE*)alloca(sizeof(HANDLE) * num_events);
for (u32 i = 0; i < num_events; i++)
event_handles[i] = reinterpret_cast<HANDLE>(events[i]->m_event_handle);
WaitForMultipleObjects(num_events, event_handles, TRUE, INFINITE);
}
#elif defined(__linux__) || defined(__APPLE__)
Event::Event(bool auto_reset /*= false*/) : m_auto_reset(auto_reset)
{
m_pipe_fds[0] = m_pipe_fds[1] = -1;
#if defined(__linux__)
pipe2(m_pipe_fds, O_NONBLOCK);
#else
pipe(m_pipe_fds);
fcntl(m_pipe_fds[0], F_SETFL, fcntl(m_pipe_fds[0], F_GETFL) | O_NONBLOCK);
fcntl(m_pipe_fds[1], F_SETFL, fcntl(m_pipe_fds[1], F_GETFL) | O_NONBLOCK);
#endif
Assert(m_pipe_fds[0] >= 0 && m_pipe_fds[1] >= 0);
}
Event::~Event()
{
close(m_pipe_fds[0]);
close(m_pipe_fds[1]);
}
void Event::Signal()
{
char buf[1] = {0};
write(m_pipe_fds[1], buf, sizeof(buf));
}
void Event::Wait()
{
pollfd pd = {};
pd.fd = m_pipe_fds[0];
pd.events = POLLRDNORM;
poll(&pd, 1, -1);
if (m_auto_reset)
Reset();
}
bool Event::TryWait(u32 timeout_in_ms)
{
pollfd pd;
pd.fd = m_pipe_fds[0];
pd.events = POLLRDNORM;
if (poll(&pd, 1, timeout_in_ms) == 0)
return false;
if (m_auto_reset)
Reset();
return true;
}
void Event::Reset()
{
char buf[1];
while (read(m_pipe_fds[0], buf, sizeof(buf)) > 0)
;
}
void Event::WaitForMultipleEvents(Event** events, u32 num_events)
{
DebugAssert(num_events > 0);
pollfd pd = {};
pd.events = POLLRDNORM;
for (u32 i = 0; i < num_events; i++)
{
pd.fd = events[i]->m_pipe_fds[0];
poll(&pd, 1, -1);
}
}
#endif
} // namespace Common

30
src/common/event.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include "types.h"
namespace Common {
class Event
{
public:
Event(bool auto_reset = false);
~Event();
void Reset();
void Signal();
void Wait();
bool TryWait(u32 timeout_in_ms);
static void WaitForMultipleEvents(Event** events, u32 num_events);
private:
#ifdef WIN32
void* m_event_handle;
#elif defined(__linux__) || defined(__APPLE__)
int m_pipe_fds[2];
bool m_auto_reset;
#else
#error Unknown platform.
#endif
};
} // namespace Common