diff options
| author | Paul Buetow <paul@buetow.org> | 2010-11-21 17:01:59 +0000 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2010-11-21 17:01:59 +0000 |
| commit | b891420946d5269cc326d67555c6aab3db41a01a (patch) | |
| tree | f6c5e7d6dbf18ec8c0ea9ec0b037251df46b4cbb /yhttpd/src/thrd | |
| parent | a537e8323d932125232c305f9573daef89aef0df (diff) | |
added yhttpd and ycurses trunk versions
Diffstat (limited to 'yhttpd/src/thrd')
| -rw-r--r-- | yhttpd/src/thrd/pool.cpp | 157 | ||||
| -rw-r--r-- | yhttpd/src/thrd/pool.h | 55 | ||||
| -rw-r--r-- | yhttpd/src/thrd/thro.cpp | 43 | ||||
| -rw-r--r-- | yhttpd/src/thrd/thro.h | 30 |
4 files changed, 285 insertions, 0 deletions
diff --git a/yhttpd/src/thrd/pool.cpp b/yhttpd/src/thrd/pool.cpp new file mode 100644 index 0000000..dd29d6a --- /dev/null +++ b/yhttpd/src/thrd/pool.cpp @@ -0,0 +1,157 @@ +#ifndef POOL_CPP +#define POOL_CPP + +#include "pool.h" + +using namespace std; + +pool::pool() +{ + pthread_mutex_init(&mut_threads, 0); + pthread_mutex_init(&mut_queue_tasks, 0); + pthread_mutex_init(&mut_num_avail_threads, 0); + pthread_cond_init(&cond_new_task, 0); + + i_num_total_threads = 0; + i_num_avail_threads = tool::string2int( wrap::CONF->get_elem( "httpd.thread.initpoolsize" ) ); + increase_pool(i_num_avail_threads); +} + +pool::~pool() +{ + pthread_mutex_lock(&mut_queue_tasks); + while (!queue_tasks.empty()) + { + delete queue_tasks.front(); + queue_tasks.pop(); + } + pthread_mutex_unlock(&mut_queue_tasks); + + pthread_mutex_destroy(&mut_threads); + pthread_mutex_destroy(&mut_queue_tasks); + pthread_mutex_destroy(&mut_num_avail_threads); + pthread_cond_destroy(&cond_new_task); +} + +int +pool::increase_pool(int i_num) +{ + wrap::system_message(POOLFLL + tool::int2string(i_num) +","+tool::int2string(i_num_total_threads)+")"); + int i_max_pool_size = tool::string2int( wrap::CONF->get_elem( "httpd.thread.maxpoolsize" ) ); + + for ( int i = 0; i < i_num; ++i ) + { + if ( i_max_pool_size != 0 && i_num_total_threads >= i_max_pool_size ) + { + wrap::system_message(POOLER2+tool::int2string(i_max_pool_size)+")"); + wrap::system_message(POOLER1+tool::int2string(i)+")"); + return i; + } + + ++i_num_total_threads; + pthread_t p_pthread; + pthread_create(&p_pthread, 0, wait_for_task, (void*) this ); + } + + return i_num; +} + +void +pool::add_task( void(*p_func)(void*), void* p_void ) +{ + pthread_mutex_lock(&mut_queue_tasks); + queue_tasks.push(new task(p_func, p_void)); + pthread_mutex_unlock(&mut_queue_tasks); + + pthread_cond_signal(&cond_new_task); + +} + +void* +pool::wait_for_task( void* p_void ) +{ + pool* p_pool = static_cast<pool*>(p_void); + + for (;;) + { + +#ifdef NCURSES + p_pool->print_pool_size(); +#endif + + pthread_mutex_lock(&p_pool->mut_threads); + pthread_cond_wait(&p_pool->cond_new_task, &p_pool->mut_threads); + + pthread_mutex_lock(&p_pool->mut_num_avail_threads); + if ( --p_pool->i_num_avail_threads < 5 ) + { + int i_size = 9 - p_pool->i_num_avail_threads; + i_size = p_pool->increase_pool(i_size); + p_pool->i_num_avail_threads += i_size; + } + pthread_mutex_unlock(&p_pool->mut_num_avail_threads); + + pthread_mutex_lock(&p_pool->mut_queue_tasks); + task* p_task = p_pool->queue_tasks.front(); + p_pool->queue_tasks.pop(); + pthread_mutex_unlock(&p_pool->mut_queue_tasks); + + pthread_mutex_unlock(&p_pool->mut_threads); + + (*(p_task->p_func))(p_task->p_void); + delete p_task; + + pthread_mutex_lock(&p_pool->mut_num_avail_threads); + p_pool->i_num_avail_threads++; + pthread_mutex_unlock(&p_pool->mut_num_avail_threads); + } + + return 0; +} + +void +pool::run(void* p_void) +{ + add_task(run_func, p_void); +} + +void +pool::run_func(void *p_void) +{ + socketcontainer* p_sock = static_cast<socketcontainer*>(p_void); + wrap::SOCK->read_write(p_sock); +} + +bool +pool::allow_user_login() +{ + pthread_mutex_lock(&mut_num_avail_threads); + if ( i_num_avail_threads < 2 ) + { + int i_max_pool_size = tool::string2int( wrap::CONF->get_elem( "httpd.thread.maxpoolsize" ) ); + if ( i_max_pool_size != 0 && i_max_pool_size == i_num_total_threads ) + { + pthread_mutex_unlock(&mut_num_avail_threads); + return false; + } + } + pthread_mutex_unlock(&mut_num_avail_threads); + + return true; +} + +#ifdef NCURSES +void +pool::print_pool_size() +{ + if ( wrap::NCUR->is_ready() ) + { + pthread_mutex_lock(&mut_num_avail_threads); + mvprintw( NCUR_POOL_WAIT_X,NCUR_POOL_WAIT_Y, "Wait/Tot: %d/%d ", i_num_avail_threads, i_num_total_threads); + mvprintw( NCUR_POOL_RUNNING_X,NCUR_POOL_RUNNING_Y, "Running: %d ", i_num_total_threads-i_num_avail_threads); + pthread_mutex_unlock(&mut_num_avail_threads); + refresh(); + } +} +#endif +#endif diff --git a/yhttpd/src/thrd/pool.h b/yhttpd/src/thrd/pool.h new file mode 100644 index 0000000..3a5f7b6 --- /dev/null +++ b/yhttpd/src/thrd/pool.h @@ -0,0 +1,55 @@ +#include "../incl.h" + +#ifndef POOL_H +#define POOL_H + +#include <queue> + +using namespace std; + +class pool +{ +private: + friend class thro; + + struct task + { + void(*p_func)(void*); + void *p_void; + + task(void(*p_func)(void*), void *p_void) + { + this->p_func = p_func; + this->p_void = p_void; + } + }; + + pthread_mutex_t mut_threads; + pthread_mutex_t mut_queue_tasks; + pthread_mutex_t mut_num_avail_threads; + pthread_cond_t cond_new_task; + + int i_num_avail_threads; + int i_num_total_threads; + + queue<task*> queue_tasks; + + int increase_pool(int i_num); + void add_task( void(*p_func)(void*), void* p_void ); + static void* wait_for_task(void *p_void); + static void run_func(void *p_void); + +public: + pool(); + ~pool(); + + void run(void* p_void); + bool allow_user_login(); + +#ifdef NCURSES + + void print_pool_size(); +#endif +}; + +#endif diff --git a/yhttpd/src/thrd/thro.cpp b/yhttpd/src/thrd/thro.cpp new file mode 100644 index 0000000..8b3f1ba --- /dev/null +++ b/yhttpd/src/thrd/thro.cpp @@ -0,0 +1,43 @@ +#ifndef THRO_CPP +#define THRO_CPP + +#include "thro.h" + +using namespace std; + +thro::thro() +{} + +thro::~thro() +{} + +void +thro::run() +{ + void *p_void; + run( p_void ); +} + +void +thro::run( void *p_void ) +{ + elem.p_thro = this; + elem.p_void = p_void; + //wrap::POOL->add_task(start_, &elem); + pthread_create( &pthread, NULL, start_, &elem ); +} + +void* +thro::start_( void *p_void ) +{ + elements *e = (elements*) p_void; + e->p_thro->start( e->p_void ); +} + +void +thro::start( void *p_void ) +{ + wrap::system_message( THRDSTR ); +} + +#endif diff --git a/yhttpd/src/thrd/thro.h b/yhttpd/src/thrd/thro.h new file mode 100644 index 0000000..8e7e0cf --- /dev/null +++ b/yhttpd/src/thrd/thro.h @@ -0,0 +1,30 @@ +#include "../incl.h" + +#ifndef THRO_H +#define THRO_H + +using namespace std; + +class thro +{ +private: + pthread_t pthread; + + struct elements + { + thro *p_thro; + void *p_void; + } + elem; + + static void *start_( void *p_void ); + +public: + thro( ); + ~thro( ); + void run(); + void run( void *p_void ); + virtual void start( void *p_void ); +}; + +#endif |
