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

172 lines
3.2 KiB
C++
Raw Normal View History

#pragma once
#include "fiber_cpp_define.hpp"
#include <list>
#include <stdlib.h>
#include "fiber_mutex.hpp"
#include "fiber_cond.hpp"
namespace acl {
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>֮<EFBFBD><EFBFBD>߳<EFBFBD>֮<EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>֮<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣͨ<EFBFBD>ţ<EFBFBD>ͨ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD>
*
* ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* class myobj {
* public:
* myobj(void) {}
* ~myobj(void) {}
*
* void test(void) { printf("hello world\r\n"); }
* };
*
* acl::fiber_tbox2<myobj> tbox;
*
* void thread_producer(void) {
* myobj o;
* tbox.push(o);
* }
*
* void thread_consumer(void) {
* myobj o;
* if (tbox.pop(o)) {
* o.test();
* }
* }
*/
2023-05-24 17:33:09 +08:00
// The fiber_tbox2 has an object copying process in push/pop which is suitable
// for transfering the object managed by std::shared_ptr.
template<typename T>
class fiber_tbox2 {
public:
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
fiber_tbox2(void) : size_(0) {}
~fiber_tbox2(void) {}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void clear(void) {
tbox_.clear();
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param t {T} <EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param notify_first {bool} <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ true<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƚ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> fiber_tbox2 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڱȽϳ<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ false <EFBFBD><EFBFBD>Ч<EFBFBD>ʸ<EFBFBD><EFBFBD>ߣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> fiber_tbox2
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڽ϶<EFBFBD>(<EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD>ߵ<EFBFBD><EFBFBD><EFBFBD> pop <EFBFBD><EFBFBD>ֱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> fiber_tbox2 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>),
* <EFBFBD>򱾲<EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ true<EFBFBD><EFBFBD><EFBFBD>Ա<EFBFBD><EFBFBD><EFBFBD> push <EFBFBD>߻<EFBFBD>û<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD> fiber_tbox2
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return {bool}
*/
bool push(T t, bool notify_first = true) {
// <20>ȼ<EFBFBD><C8BC><EFBFBD>
if (mutex_.lock() == false) {
abort();
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
tbox_.push_back(t);
size_++;
if (notify_first) {
if (cond_.notify() == false) {
abort();
}
if (mutex_.unlock() == false) {
abort();
}
return true;
} else {
if (mutex_.unlock() == false) {
abort();
}
if (cond_.notify() == false) {
abort();
}
return true;
}
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param t {T&} <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> true ʱ<EFBFBD><EFBFBD><EFBFBD>Ž<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param wait_ms {int} >= 0 ʱ<EFBFBD><EFBFBD><EFBFBD>õȴ<EFBFBD><EFBFBD><EFBFBD>ʱʱ<EFBFBD><EFBFBD>(<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD>ȴ<EFBFBD>ֱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return {bool} <EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
bool pop(T& t, int wait_ms = -1) {
if (mutex_.lock() == false) {
abort();
}
while (true) {
if (peek_obj(t)) {
if (mutex_.unlock() == false) {
abort();
}
return true;
}
if (!cond_.wait(mutex_, wait_ms) && wait_ms >= 0) {
if (mutex_.unlock() == false) {
abort();
}
return false;
}
}
}
/**
* <EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return {size_t}
*/
size_t size(void) const {
return size_;
}
public:
void lock(void) {
if (mutex_.lock() == false) {
abort();
}
}
void unlock(void) {
if (mutex_.unlock() == false) {
abort();
}
}
private:
fiber_tbox2(const fiber_tbox2&) {}
const fiber_tbox2& operator=(const fiber_tbox2&);
private:
std::list<T> tbox_;
size_t size_;
fiber_mutex mutex_;
fiber_cond cond_;
bool peek_obj(T& t) {
typename std::list<T>::iterator it = tbox_.begin();
if (it == tbox_.end()) {
return false;
}
size_--;
t = *it;
tbox_.erase(it);
return true;
}
};
} // namespace acl