示例#1
0
/* execute the task callback function. */
static int task_func(void *argv) {
	struct kqueuemgr *mgr = (struct kqueuemgr *)argv;
	struct kevent *ev;
	struct socketer *sock;
	for (;;) {
		if (mgr->need_exit)
			return -1;
		ev = pop_event(mgr);
		if (!ev)
			return 0;
		assert(ev->udata != NULL);
		sock = (struct socketer *)ev->udata;

		/* error event. */
		if (ev->flags & EV_EOF || ev->flags & EV_ERROR) {
			socketer_close(sock);
			continue;
		}

		if (ev->filter == EVFILT_READ) {
			/* can read event. */
			if (catomic_compare_set(&sock->recvlock, 0, 1)) {
				catomic_inc(&sock->ref);
			}
			socketer_on_recv(sock, 0);
		} else 	if (ev->filter == EVFILT_WRITE) {
			/* can write event. */
			if (catomic_compare_set(&sock->sendlock, 0, 1)) {
				catomic_inc(&sock->ref);
			}
			socketer_on_send(sock, 0);
		}
	}
}
示例#2
0
static void th_pro_func(cthread *th) {
	int cinfo_id = 0;
	struct cthread_info *cinfo = (struct cthread_info *)cthread_get_udata(th);
	struct cthread_pool *mgr = cinfo->mgr;

	/* first suspend. */
	cthread_suspend(cthread_info_get_handle_ptr(cinfo));

	/* check need run. */
	if (catomic_read(&mgr->run) == 0)
		return;

	cinfo_id = (int)cthread_info_get_id(cinfo);
	(void)cinfo_id;

	cthread_info_state_to_activity(cinfo);
	catomic_inc(&mgr->resume_num);
	catomic_inc(&mgr->activity_num);
	catomic_inc(&mgr->need_exit_num);

	/* wait all run to here. */
	while (catomic_read(&mgr->need_exit_num) != (int64)mgr->thread_num) {
		cthread_self_sleep(0);
	}

	thread_pool_debuglog("func:[%s][start thread] id:%d", 
			__FUNCTION__, cthread_info_get_id(cinfo));

	while (catomic_read(&mgr->run) != 0) {
		if (cthread_info_is_header(cinfo)) {
			/*
			 * do leader function,
			 * if return value less than 0, then exit.
			 * if return value greater than 0, then is need resume thread num.
			 */
			int resume_num = mgr->func_leader(mgr->udata);
			if (resume_num > 0) {
				int real_resume_num = (int)min(resume_num, catomic_read(&mgr->need_exit_num));

				thread_pool_debuglog("func:[%s][leader func return] leader thread id:%d, "
						"resume_num:%d, activity num:%d, exit num:%d, has_leader:%d",
						__FUNCTION__, cthread_info_get_id(cinfo), resume_num, 
						(int)catomic_read(&mgr->activity_num), (int)catomic_read(&mgr->exit_num), 
						(int)catomic_read(&mgr->has_leader));

				cthread_info_change_to_henchman(cinfo);

				catomic_set(&mgr->has_leader, 0);
				catomic_set(&mgr->resume_num, real_resume_num);

				cthread_pool_resume_some_thread(mgr, real_resume_num - 1, cinfo);
			} else if (resume_num < 0) {
				break;
			}

		} else {

			/*
			 * do task function,
			 * the return value is not equal to 0, then exit.
			 */
			if (mgr->func_task(mgr->udata) != 0)
				break;

			/* If own is the last activity of the followers, set own to leader. */
			if (catomic_dec(&mgr->resume_num) == 0) {

				assert(catomic_read(&mgr->activity_num) >= 1);
				assert(catomic_read(&mgr->has_leader) == 0);

				/* competition leader. */
				if (catomic_compare_set(&mgr->has_leader, 0, 1)) {

					/* change own to leader. */
					cthread_info_change_to_header(cinfo);

					thread_pool_debuglog("func:[%s][change to leader] task thread id:%d, "
							"activity num:%d, exit num:%d, has_leader:%d",
							__FUNCTION__, cthread_info_get_id(cinfo),
							(int)catomic_read(&mgr->activity_num), (int)catomic_read(&mgr->exit_num), 
							(int)catomic_read(&mgr->has_leader));

					continue;
				}

				assert(false && "is last activity thread, but not change to leader, error!");
				log_error("is last activity thread, but not change to leader, error!");

			}

			/* suspend. */
			cthread_info_state_to_suspend(cinfo);
			catomic_dec(&mgr->activity_num);
			catomic_inc(&mgr->suspend_num);

			thread_pool_debuglog("func:[%s][suspend thread] thread id:%d, activity num:%d, "
					"exit num:%d, has_leader:%d", __FUNCTION__, cthread_info_get_id(cinfo),
					(int)catomic_read(&mgr->activity_num), (int)catomic_read(&mgr->exit_num), 
					(int)catomic_read(&mgr->has_leader));

			/* real do suspend. */
			cthread_suspend(cthread_info_get_handle_ptr(cinfo));

			/* from resume. */
			cthread_info_state_to_activity(cinfo);
			catomic_dec(&mgr->suspend_num);
			catomic_inc(&mgr->activity_num);

			thread_pool_debuglog("func:[%s][thread for resume] thread id:%d, activity num:%d, "
					"exit num:%d, has_leader:%d", __FUNCTION__,	cthread_info_get_id(cinfo),
					(int)catomic_read(&mgr->activity_num), (int)catomic_read(&mgr->exit_num), 
					(int)catomic_read(&mgr->has_leader));
		}
	}

	cthread_pool_do_thread_exit(cinfo);
}