⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cond.c

📁 多线程库
💻 C
字号:
#include <thread.h>#include <thread_lists.h>#include <thread_signal_num.h>#include "wait_queue.h"#include "shared.h"extern "C" {#	include <errno.h>#       include <sys/time.h>#       include <unistd.h>#       include <signal.h>};char *cond::c_project = 0;//// Conditional variables.  This variable consists of a single// spinlock structure, and a couple of function to control// activity around it.  And a list of threads that are waiting// on that condition.cond::cond(attributes::scope p_scope){  c_id = -1;  if ( p_scope == attributes::process_shared )    c_id = shared_mem::share.create_proj( c_project );  c_waiting = new wait_queue( c_id );  c_scope = p_scope;}cond::cond(){  c_waiting = new wait_queue;  c_scope = attributes::process_private;}cond::~cond(){  if ( c_waiting->empty() == false )    broadcast();  delete c_waiting;}attributes::scope cond::scope(){  return c_scope;}//// Wait for a signal to arrive through the conditional variable.// mutex is considered lock on entry, and is unlock during the// time we wait for the signal to arrive.  The mutex is relocked// before returning.int cond::wait(mutex& _mutx){  thread_list::iterator i = thread_list::__threads.locate(getpid());  if ( i != thread_list::__threads.end()) {    _mutx.unlock();    c_waiting->suspend_me();    _mutx.lock();    if ((*i)->canceled() && (*i)->cancelstate() == pthread::cancel_enable) {      c_waiting->remove((*i)->id());      (*i)->exit(PTHREAD_CANCELED);    }  }  return 0;}//// timedwait relative.//// wait for a specific time, for a signal to arrive, or for a// cancelation to occur.  As with wait, mutex is considered// lock on entry, and is unlocked during the wait for the// signal.  It is relocked, after the duration transpires.int cond::timedwait_rel(mutex& _mutx, const struct timespec *_spec){  thread_list::iterator i = thread_list::__threads.locate(getpid());  sigset_t unblock, initial_mask;  int retsleep = -1;  sigjmp_buf jmpbuf;  if (i == thread_list::__threads.end())    return ESRCH;  c_waiting->insert((*i)->id());  _mutx.unlock();  if (sigsetjmp(jmpbuf, 0) == 0) {    (*i)->set(pthread::signal_jmp, &jmpbuf);    (*i)->signal(0);    if (!((*i)->canceled() && (*i)->cancelstate() == pthread::cancel_enable)) {      sigemptyset(&unblock);      sigaddset(&unblock, PTHREAD_SIG_RESTART);      sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask);      retsleep = nanosleep(_spec, NULL);      sigprocmask(SIG_SETMASK, &initial_mask, NULL);    }  }  (*i)->set(pthread::signal_jmp, 0);  if ((*i)->canceled() && (*i)->cancelstate() == pthread::cancel_enable) {    c_waiting->remove((*i)->id());    _mutx.lock();    (*i)->exit(PTHREAD_CANCELED);  }  if ((*i)->signal() == 0) {    c_waiting->remove((*i)->id());    _mutx.lock();    return retsleep ? EINTR : ETIMEDOUT;  }  _mutx.lock();  return 0;}//// timedwait//// Wait for a specific time period, for a signal to occur.  This// routine simple calculates the relative time, from the given// time and current time.  Then uses timedwait relative to// perform the actual wait.int cond::timedwait(mutex& _mutx, const struct timespec *_spec){  struct timeval now;  struct timespec reltime;  gettimeofday(&now, NULL);  reltime.tv_sec = _spec->tv_sec - now.tv_sec;  reltime.tv_nsec = _spec->tv_nsec - now.tv_usec * 1000;  if (reltime.tv_nsec < 0) {    reltime.tv_nsec += 1000000000;    reltime.tv_sec -= 1;  }  if (reltime.tv_sec < 0)    return ETIMEDOUT;  return timedwait_rel(_mutx, &reltime);}//// signal//// send a signal to the next process waiting on the list.int cond::signal(){  c_waiting->wake_up();  return 0;}//// broadcast//// send a signal to every process on the list.int cond::broadcast(){  while( !c_waiting->empty() )    c_waiting->wake_up();  return 0;}//// project_part//// change the project partvoidcond::project_part(const char *p_part){  if ( c_project == 0 )    c_project = new char[80];  c_project[0] = 0;  if ( p_part )    strcpy( c_project,p_part );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -