Exemplo n.º 1
0
static void worker_exit(Worker *worker, bool force)
{
	if( !worker ) {
		return;
	}

	int worker_id = worker->m_id;

	bool need_remove = force;
	if( ioprocess ) {
		ioprocess->LockWorkerList();

		if( need_remove == false ) {
			if( ioprocess->m_avail_workers_num > ioprocess->m_min_workers ) {
				need_remove = true;
			}
		}

		if( need_remove ) {
			// worker will be deleted inside removeWorkerFromWorkerList
			ioprocess->removeWorkerFromWorkerList(worker->m_id);
			worker = NULL;
			ioprocess->m_avail_workers_num--;

		}
		ioprocess->UnlockWorkerList();
	}

	if( need_remove ) {
		dprintf(D_FULLDEBUG, "Thread(%d) is exiting...\n", worker_id); 

		int retval = 0;
		amazon_gahp_release_big_mutex();
		pthread_exit(&retval);
	}else {
		//dprintf(D_FULLDEBUG, "Thread(%d) is going to be used again\n",
		//		worker_id);

		// We need to keep this thread running
//		pthread_mutex_lock(&worker->m_mutex);

		worker->m_can_use = true;

		worker->m_is_doing = false;
		worker->m_is_waiting = false;
		worker->m_must_be_alive = false;

//		pthread_mutex_unlock(&worker->m_mutex);
	}
}
Exemplo n.º 2
0
static void *worker_function( void *ptr )
{
	Worker *worker = (Worker *)ptr;

		/* Our new thread should grab the big mutex before starting.
		 * We will then
		 * release it and let other threads run when we would otherwise
		 * block.
		 */
	amazon_gahp_grab_big_mutex();

	if( !worker ) {
		dprintf (D_ALWAYS, "Ooops!! No input Data in worker thread\n");
		amazon_gahp_release_big_mutex();
		return NULL;
	}

	// Pop Request
	Request *new_request = NULL;
	struct timespec ts;
	struct timeval tp;

	while(1) {

		worker->m_is_doing = false;
		worker->m_is_waiting = false;

		if( worker->m_can_use == false ) {
			// Need to die
			worker_exit(worker, true);
		}

		while( (new_request = popRequest(worker)) == NULL ) {

			worker->m_is_waiting = true;

			// Get Current Time
			gettimeofday(&tp, NULL);

			/* Convert from timeval to timespec */
			ts.tv_sec = tp.tv_sec;
			ts.tv_nsec = tp.tv_usec * 1000;
			ts.tv_sec += WORKER_MANAGER_TIMER_INTERVAL;

			if( ioprocess ) {
				if( ioprocess->numOfPendingRequest() > 0 ) {
					continue;
				}
			}

			int retval = pthread_cond_timedwait(&worker->m_cond,
					&global_big_mutex, &ts);

			if( worker->m_can_use == false ) {
				// Need to die
				worker->m_is_waiting = false;
				worker_exit(worker, true);
			} else {
				// If timeout happends, need to check m_must_be_alive
				if( retval == ETIMEDOUT ) {
					if( ioprocess ) {
						if( ioprocess->numOfPendingRequest() > 0 ) {
							continue;
						}
					}

					if( !worker->m_must_be_alive ) {
						// Need to die according to the min number of workers

						worker->m_is_waiting = false;
						worker->m_can_use = false;

						worker_exit(worker, false);
					} else {
						dprintf(D_FULLDEBUG, "Thread(%d) must be alive for "
								"another request\n", worker->m_id);
					}
				}
			}
		}

		worker->m_is_doing = true;
		worker->m_is_waiting = false;
		worker->m_must_be_alive = false;

		if(!handle_gahp_command(new_request) ) {
			dprintf(D_ALWAYS, "ERROR (io_loop) processing %s\n",
					new_request->m_raw_cmd.c_str());
		} else {
			dprintf(D_FULLDEBUG, "CMD(\"%s\") is done with result %s",
					new_request->m_raw_cmd.c_str(),
					new_request->m_result.c_str());
		}

		// Now we processed one request
		delete new_request;
		new_request = NULL;

	}

	amazon_gahp_release_big_mutex();
	return NULL;
}