73 #ifndef CGU_ASYNC_CHANNEL_H 
   74 #define CGU_ASYNC_CHANNEL_H 
   87 #ifdef CGU_USE_SCHED_YIELD 
   99   --(*
static_cast<std::size_t*
>(arg));
 
  200   enum Status {normal, closed, destructing} status;
 
  249     if (status == normal) {
 
  279     bool waiting = 
false;
 
  281     if (status != normal) 
return false;
 
  292     while (size >= n && status == normal) {
 
  300     pthread_cleanup_pop(
false);
 
  304     Status local_status = status;
 
  305     if (waiting) --waiters;
 
  306     if (local_status != normal) 
return false;
 
  309     new (
static_cast<void*
>(buf + next)) T{obj};
 
  340     bool waiting = 
false;
 
  342     if (status != normal) 
return false;
 
  353     while (size >= n && status == normal) {
 
  361     pthread_cleanup_pop(
false);
 
  365     Status local_status = status;
 
  366     if (waiting) --waiters;
 
  367     if (local_status != normal) 
return false;
 
  370     new (
static_cast<void*
>(buf + next)) T{std::move(obj)};
 
  401   template<
class... Args>
 
  403     bool waiting = 
false;
 
  405     if (status != normal) 
return false;
 
  416     while (size >= n && status == normal) {
 
  424     pthread_cleanup_pop(
false);
 
  428     Status local_status = status;
 
  429     if (waiting) --waiters;
 
  430     if (local_status != normal) 
return false;
 
  433     new (
static_cast<void*
>(buf + next)) T{std::forward<Args>(args)...};
 
  465     bool waiting = 
false;
 
  477     while (!size && status == normal) {
 
  485     pthread_cleanup_pop(
false);
 
  487     if (status == destructing) {
 
  490       if (waiting) --waiters;
 
  497       if (idx == n) idx = 0;
 
  505     if (waiting) --waiters;
 
  509       if (waiting) --waiters;
 
  514       if (waiting) --waiters;
 
  555     bool waiting = 
false;
 
  567     while (!size && status == normal) {
 
  575     pthread_cleanup_pop(
false);
 
  577     if (status == destructing) {
 
  580       if (waiting) --waiters;
 
  585       obj = std::move(buf[old_idx]);
 
  587       if (idx == n) idx = 0;
 
  595     if (waiting) --waiters;
 
  599       if (waiting) --waiters;
 
  604       if (waiting) --waiters;
 
  646                   buf(static_cast<T*>(std::malloc(sizeof(T) * n))) {
 
  647     static_assert(n != 0, 
"AsyncChannel objects may not be created with size 0");
 
  648     if (!buf) 
throw std::bad_alloc();
 
  666     status = destructing;
 
  678 #ifdef CGU_USE_SCHED_YIELD 
  692       if (idx == n) idx = 0;
 
  703 #ifndef DOXYGEN_PARSING 
  710 class AsyncChannel<T, 1> {
 
  715   mutable Thread::Mutex mutex;
 
  719   enum Status {normal, closed, destructing} status;
 
  730   void close() noexcept {
 
  731     Thread::Mutex::Lock lock{mutex};
 
  732     if (status == normal) {
 
  739     bool waiting = 
false;
 
  740     Thread::Mutex::Lock lock{mutex};
 
  741     if (status != normal) 
return false;
 
  752     while (full && status == normal) {
 
  759     Thread::CancelBlock b;
 
  760     pthread_cleanup_pop(
false);
 
  764     Status local_status = status;
 
  765     if (waiting) --waiters;
 
  766     if (local_status != normal) 
return false;
 
  767     new (
static_cast<void*
>(datum)) T{obj};
 
  774     bool waiting = 
false;
 
  775     Thread::Mutex::Lock lock{mutex};
 
  776     if (status != normal) 
return false;
 
  787     while (full && status == normal) {
 
  794     Thread::CancelBlock b;
 
  795     pthread_cleanup_pop(
false);
 
  799     Status local_status = status;
 
  800     if (waiting) --waiters;
 
  801     if (local_status != normal) 
return false;
 
  802     new (
static_cast<void*
>(datum)) T{std::move(obj)};
 
  808   template<
class... Args>
 
  810     bool waiting = 
false;
 
  811     Thread::Mutex::Lock lock{mutex};
 
  812     if (status != normal) 
return false;
 
  823     while (full && status == normal) {
 
  830     Thread::CancelBlock b;
 
  831     pthread_cleanup_pop(
false);
 
  835     Status local_status = status;
 
  836     if (waiting) --waiters;
 
  837     if (local_status != normal) 
return false;
 
  838     new (
static_cast<void*
>(datum)) T{std::forward<Args>(args)...};
 
  845     bool waiting = 
false;
 
  846     Thread::Mutex::Lock lock{mutex};
 
  857     while (!full && status == normal) {
 
  864     Thread::CancelBlock b;
 
  865     pthread_cleanup_pop(
false);
 
  867     if (status == destructing) {
 
  870       if (waiting) --waiters;
 
  882     if (waiting) --waiters;
 
  886       if (waiting) --waiters;
 
  891       if (waiting) --waiters;
 
  897     bool waiting = 
false;
 
  898     Thread::Mutex::Lock lock{mutex};
 
  909     while (!full && status == normal) {
 
  916     Thread::CancelBlock b;
 
  917     pthread_cleanup_pop(
false);
 
  919     if (status == destructing) {
 
  922       if (waiting) --waiters;
 
  926       obj = std::move(*datum);
 
  934     if (waiting) --waiters;
 
  938       if (waiting) --waiters;
 
  943       if (waiting) --waiters;
 
  948   AsyncChannel(): waiters(0), full(false), status(normal),
 
  958                   datum(static_cast<T*>(std::malloc(sizeof(T)))) {
 
  959     if (!datum) 
throw std::bad_alloc();
 
  964     status = destructing;
 
  976 #ifdef CGU_USE_SCHED_YIELD 
  987     if (full) datum->~T();
 
  994 #endif // DOXYGEN_PARSING 
  998 #endif // CGU_ASYNC_CHANNEL_H