acl/lib_fiber/cpp/include/fiber/fiber_sem.hpp

139 lines
2.3 KiB
C++
Raw Normal View History

#pragma once
2018-11-30 14:38:22 +08:00
#include "fiber_cpp_define.hpp"
#include <list>
#include <assert.h>
2018-11-30 14:38:22 +08:00
struct ACL_FIBER_SEM;
namespace acl {
typedef enum {
fiber_sem_t_sync = 0,
fiber_sem_t_async = (1 << 0),
} fiber_sem_attr_t;
2023-06-11 18:34:41 +08:00
class FIBER_CPP_API fiber_sem {
2018-11-30 14:38:22 +08:00
public:
fiber_sem(int max, fiber_sem_attr_t attr = fiber_sem_t_async);
2018-11-30 14:38:22 +08:00
~fiber_sem(void);
int wait(void);
int trywait(void);
int post(void);
size_t num(void) const;
2018-11-30 14:38:22 +08:00
private:
ACL_FIBER_SEM* sem_;
fiber_sem(const fiber_sem&);
const fiber_sem& operator=(const fiber_sem&);
};
2023-06-11 18:34:41 +08:00
class FIBER_CPP_API fiber_sem_guard {
2018-11-30 14:38:22 +08:00
public:
2023-06-11 18:34:41 +08:00
fiber_sem_guard(fiber_sem& sem) : sem_(sem) {
2018-11-30 14:38:22 +08:00
(void) sem_.wait();
}
2023-06-11 18:34:41 +08:00
~fiber_sem_guard(void) {
2018-11-30 14:38:22 +08:00
sem_.post();
}
private:
fiber_sem& sem_;
fiber_sem_guard(const fiber_sem_guard&);
void operator=(const fiber_sem_guard&);
2018-11-30 14:38:22 +08:00
};
template<typename T>
2023-06-11 18:34:41 +08:00
class fiber_sbox {
public:
2023-06-12 11:36:02 +08:00
fiber_sbox(bool free_obj = true, bool async = true)
: sem_(0, async ? fiber_sem_t_async : fiber_sem_t_sync)
2023-06-12 11:36:02 +08:00
, free_obj_(free_obj) {}
~fiber_sbox(void) { clear(free_obj_); }
void push(T* t) {
sbox_.push_back(t);
sem_.post();
}
2023-06-12 11:36:02 +08:00
T* pop(bool* found = NULL) {
if (sem_.wait() < 0) {
if (found) {
*found = false;
}
return NULL;
}
T* t = sbox_.front();
sbox_.pop_front();
2023-06-12 11:36:02 +08:00
if (found) {
*found = true;
}
return t;
}
2023-06-12 18:27:07 +08:00
size_t size(void) const {
return sem_.num();
}
private:
fiber_sem sem_;
std::list<T*> sbox_;
bool free_obj_;
fiber_sbox(const fiber_sbox&);
void operator=(const fiber_sbox&);
2023-06-11 18:34:41 +08:00
void clear(bool free_obj = false) {
if (free_obj) {
for (typename std::list<T*>::iterator it =
sbox_.begin(); it != sbox_.end(); ++it) {
delete *it;
}
}
sbox_.clear();
}
};
template<typename T>
class fiber_sbox2 {
public:
2023-06-12 11:36:02 +08:00
fiber_sbox2(bool async = true)
: sem_(0, async ? fiber_sem_t_async : fiber_sem_t_sync) {}
2023-06-12 11:36:02 +08:00
~fiber_sbox2(void) {}
void push(T t) {
sbox_.push_back(t);
sem_.post();
}
2023-06-12 11:36:02 +08:00
bool pop(T& t) {
if (sem_.wait() < 0) {
return false;
}
t = sbox_.front();
sbox_.pop_front();
2023-06-12 11:36:02 +08:00
return true;
}
size_t size(void) const {
return sem_.num();
}
private:
fiber_sem sem_;
std::list<T> sbox_;
fiber_sbox2(const fiber_sbox2&);
void operator=(const fiber_sbox2&);
};
2018-11-30 14:38:22 +08:00
} // namespace acl