Skip to content

Commit

Permalink
EGE/include/thread_queue.h: 移除 Lock 类; thread_queue 类模板使用标准库的同步设施。
Browse files Browse the repository at this point in the history
Signed-off-by: FrankHB <frankhb1989@gmail.com>
  • Loading branch information
FrankHB committed Jan 17, 2015
1 parent ed93446 commit 3f8b41a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 42 deletions.
6 changes: 4 additions & 2 deletions Compatibility.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Code::Blocks 。
移除类型 LPCALLBACK_PROC 、LPMSG_KEY_PROC 、LPMSG_MOUSE_PROC 、MSG_KEY_PROC 和 MSG_MOUSE_PROC ,其中 LPCALLBACK_PROC 可用 CALLBACK_PROC* 代替,
添加 linestyletype 和 EGEMSG 的构造函数,只支持默认构造和提供所有成员的初始化。
移除枚举 graphics_modes 。
移除类 Lock ,使用 std::lock_guard 等代替。

向后(源代码)兼容但不保证向前兼容原始实现的接口
----
Expand All @@ -57,10 +58,11 @@ LPSTR → char* 。
LPCSTR → const char* 。
LPWSTR → const wchar_t* 。
LPCWSTR → const wchar_t* 。
VOID → void 。
PVOID → void* 。
LPVOID → void* 。
VOID → void 。
DWORD → unsigned long 。
PDWORD → unsigned long*。
DWORD_PTR → ::ULONG_PTR 。
所有同名 typedef 结构体名称或 typedef 匿名结构体调整为非 typedef 结构体类型名。
宏 EGEAPI 调整至返回值前;移除函数形参中不必要的 const 。
Expand Down Expand Up @@ -97,10 +99,10 @@ DWORD_PTR → ::ULONG_PTR 。
移除 CONVERT_IMAGE_END 、CONVERT_IMAGE_F 和 CONVERT_IMAGE_F_CONST 宏。
移除 setrendermode 实现所需的计时器例程;主窗口消息循环不响应 WM_TIMER 。
取消手动设置 exit_window 状态,改用 UI 线程状态表示;移除无用的 exit_flag 。
类型 PDWORD 用 DWORD* 代替。
类 IMAGE :修复复制构造;新增交换、转移构造和统一赋值操作;移除成员初始化检查;封装部分成员保证不可在外部修改。
CONVERT_IMAGE 和 CONVERT_IMAGE_CONST 宏改用内联函数实现,且当输入除空指针值外返回原值。
命名空间作用域静态函数和对象去除 static 并使用未命名命名空间代替。
thread_queue 类模板使用标准库的同步设施实现。

实现质量(QoI)
----
Expand Down
74 changes: 34 additions & 40 deletions EGE/include/thread_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,98 +2,92 @@
#define INC_thread_queue_h_

#include <windows.h>
#include <mutex>

#define QUEUE_LEN 1024

namespace ege
{

class Lock
{
public:
Lock(LPCRITICAL_SECTION p_) : _psection(p_)
{
::EnterCriticalSection(_psection);
}
~Lock()
{
::LeaveCriticalSection(_psection);
}
private:
LPCRITICAL_SECTION _psection;
};

template<typename T>
class thread_queue
{
private:
std::mutex mtx;
T _queue[QUEUE_LEN];
T _last;
int _r = 0, _w = 0;

public:
thread_queue(void)
{
::InitializeCriticalSection(&_section);
_r = _w = 0;
}
~thread_queue(void)
void
push(const T& d_)
{
::DeleteCriticalSection(&_section);
}
std::lock_guard<std::mutex> lck(mtx);

void push(const T& d_)
{
Lock lock(&_section);
int w = (_w + 1) % QUEUE_LEN;
_queue[w] = d_;
if(w == _r)
_r = (_r + 1) % QUEUE_LEN;
_w = w;
}
int pop(T& d_)

int
pop(T& d_)
{
Lock lock(&_section);
std::lock_guard<std::mutex> lck(mtx);

if(_w == _r)
return 0;
d_ = _queue[_r];
_last = d_;
_r = (_r + 1) % QUEUE_LEN;
return 1;
}
int unpop()

int
unpop()
{
Lock lock(&_section);
std::lock_guard<std::mutex> lck(mtx);

if(_r == (_w + 1) % QUEUE_LEN)
return 0;
_r = (_r + QUEUE_LEN - 1) % QUEUE_LEN;
return 1;
}
T last()

T
last()
{
return _last;
}

template<typename F>
void process(F&& process_func)
void
process(F&& process_func)
{
Lock lock(&_section);
std::lock_guard<std::mutex> lck(mtx);
int r = _r;
int w = _w;

if(r != w)
{
if(w < r) w += QUEUE_LEN;

for(; r <= w; r++)
{
int pos = r % QUEUE_LEN;
process_func(_queue[pos]);
}
}
}
bool empty()

bool
empty()
{
Lock lock(&_section);
std::lock_guard<std::mutex> lck(mtx);

return _r == _w;
}
private:
CRITICAL_SECTION _section;
T _queue[QUEUE_LEN];
T _last;
int _r, _w;
};

}
Expand Down

0 comments on commit 3f8b41a

Please sign in to comment.