void reload_task(void *data) { RELOAD_TASK = taskself(); struct ServerTask *srv = data; while(1) { taskswitch(); task_clear_signal(); if(RELOAD) { log_info("Reload requested, will load %s from %s", bdata(srv->db_file), bdata(srv->server_id)); Server *old_srv = Server_queue_latest(); Server *new_srv = reload_server(old_srv, bdata(srv->db_file), bdata(srv->server_id)); check(new_srv, "Failed to load the new configuration, exiting."); // for this to work handlers need to die more gracefully Server_queue_push(new_srv); } else { log_info("Shutdown requested, goodbye."); break; } } taskexit(0); error: taskexit(1); }
void Handler_task(void *v) { int rc = 0; int i = 0; Handler *handler = (Handler *)v; HandlerParser *parser = NULL; int max_targets = Setting_get_int("limits.handler_targets", 128); log_info("MAX allowing limits.handler_targets=%d", max_targets); parser = HandlerParser_create(max_targets); check_mem(parser); check(Handler_setup(handler) == 0, "Failed to initialize handler, exiting."); while(handler->running && !task_was_signaled()) { taskstate("delivering"); rc = handler_recv_parse(handler, parser); if(task_was_signaled()) { log_warn("Handler task signaled, exiting."); break; } else if( rc == -1 || parser->target_count <= 0) { log_warn("Skipped invalid message from handler: %s", bdata(handler->send_spec)); taskdelay(100); continue; } else { for(i = 0; i < (int)parser->target_count; i++) { int id = (int)parser->targets[i]; int fd = Register_fd_for_id(id); Connection *conn = fd == -1 ? NULL : Register_fd_exists(fd); // don't bother calling process request if there's nothing to handle if(conn && fd >= 0) { handler_process_request(handler, id, fd, conn, parser->body); } else { // TODO: I believe we need to notify the connection that it is dead too Handler_notify_leave(handler, id); } } } HandlerParser_reset(parser); } handler->running = 0; handler->task = NULL; HandlerParser_destroy(parser); taskexit(0); error: log_err("HANDLER TASK DIED: %s", bdata(handler->send_spec)); handler->running = 0; handler->task = NULL; HandlerParser_destroy(parser); taskexit(1); }
void Connection_task(void *v) { Connection *conn = (Connection *)v; int i = 0; int next = OPEN; State_init(&conn->state, &CONN_ACTIONS); while(1) { if(Filter_activated()) { next = Filter_run(next, conn); check(next >= CLOSE && next < EVENT_END, "!!! Invalid next event[%d]: %d from filter!", i, next); } if(next == CLOSE) break; next = State_exec(&conn->state, next, (void *)conn); check(next >= CLOSE && next < EVENT_END, "!!! Invalid next event[%d]: %d, Tell ZED!", i, next); if(conn->iob && !conn->iob->closed) { Register_ping(IOBuf_fd(conn->iob)); } i++; } error: // fallthrough State_exec(&conn->state, CLOSE, (void *)conn); Connection_destroy(conn); taskexit(0); }
void Handler_task(void *v) { int rc = 0; int i = 0; Handler *handler = (Handler *)v; HandlerParser *parser = NULL; int max_targets = Setting_get_int("limits.handler_targets", 128); log_info("MAX allowing limits.handler_targets=%d", 128); parser = HandlerParser_create(max_targets); check_mem(parser); check(Handler_setup(handler) == 0, "Failed to initialize handler, exiting."); while(handler->running) { taskstate("delivering"); rc = handler_recv_parse(handler, parser); if(rc != -1 && parser->target_count > 0) { for(i = 0; i < (int)parser->target_count; i++) { int id = (int)parser->targets[i]; int fd = Register_fd_for_id(id); Connection *conn = (Connection *)Register_fd_exists(fd); handler_process_request(handler, id, fd, conn, parser->body); } } else { debug("Skipped invalid message from handler: %s", bdata(handler->send_spec)); } HandlerParser_reset(parser); } HandlerParser_destroy(parser); debug("HANDLER EXITED."); taskexit(0); error: HandlerParser_destroy(parser); log_err("HANDLER TASK DIED"); taskexit(1); }
void taskmain(int argc, char *argv[]) { LOG_FILE = stderr; glob_t profile_glob; int rc = 0; int i = 0; Action *action = NULL; tst_t *targets = NULL; bstring pid_file = NULL; check(argc == 3, "USAGE: procer <profile_dir> <procer_pid_file>"); pid_file = bfromcstr(argv[2]); rc = Unixy_remove_dead_pidfile(pid_file); check(rc == 0, "Failed to remove %s, procer is probably already running.", bdata(pid_file)); rc = Unixy_daemonize(); check(rc == 0, "Couldn't daemonize, that's not good."); rc = chdir(argv[1]); check(rc == 0, "Couldn't change to %s profile dir.", argv[1]); rc = Unixy_pid_file(pid_file); check(rc == 0, "Failed to make the PID file: %s", bdata(pid_file)); FILE *log = fopen("error.log", "a+"); check(log, "Couldn't open error.log"); setbuf(log, NULL); LOG_FILE = log; bstring dir_glob = bformat("%s/[A-Za-z0-9]*", argv[1]); check(dir_glob, "Couldn't make the directory glob."); rc = glob(bdata(dir_glob), GLOB_ERR | GLOB_ONLYDIR, NULL, &profile_glob); check(rc == 0, "Failed to find directories in the profiles."); debug("Loading %zu actions.", profile_glob.gl_pathc); for(i = 0; i < profile_glob.gl_pathc; i++) { action = Action_create(profile_glob.gl_pathv[i]); targets = tst_insert(targets, bdata(action->name), blength(action->name), action); } // now we setup the dependencies from the settings they've got tst_traverse(targets, Action_dependency_assign, targets); tst_traverse(targets, Action_start_all, NULL); taskexit(0); error: taskexitall(1); }
static void taskstart(uint y, uint x) { Task *t; ulong z; z = x << 16; /* hide undefined 32-bit shift from 32-bit compilers */ z <<= 16; z |= y; t = (Task *) z; t->startfn(t->startarg); taskexit(0); }
void fdtask(void *v) { int i, ms; PollResult result; int rc = 0; rc = PollResult_init(POLL, &result); check(rc == 0, "Failed to initialize the poll result."); tasksystem(); taskname("fdtask"); for(;;){ /* let everyone else run */ while(taskyield() > 0) ; /* we're the only one runnable - poll for i/o */ errno = 0; taskstate("poll"); ms = next_task_sleeptime(500); if(SIGNALED) { for(i = 0; i < SuperPoll_active_hot(POLL); i++) { Task *target = (Task *)SuperPoll_data(POLL, i); if(target) taskready(target); SuperPoll_compact_down(POLL, i); } } else { rc = SuperPoll_poll(POLL, &result, ms); check(rc != -1, "SuperPoll failure, aborting."); for(i = 0; i < rc; i++) { taskready(result.hits[i].data); } } wake_sleepers(); } PollResult_clean(&result); taskexit(0); error: taskexitall(1); }
static void taskstart(uint y, uint x) { Task *t; ulong z; z = x<<16; /* hide undefined 32-bit shift from 32-bit compilers */ z <<= 16; z |= y; t = (Task*)z; //print("taskstart %p\n", t); t->startfn(t->startarg); //print("taskexits %p\n", t); taskexit(0); //print("not reacehd\n"); }
static void taskstart(uint y, uint x) { Task *t; ulong z; //将2个四字节组成一个8字节64位的地址,指向了所属的Task结构 z = x<<16; /* hide undefined 32-bit shift from 32-bit compilers */ z <<= 16; z |= y; t = (Task*)z; //print("taskstart %p\n", t); t->startfn(t->startarg);//调用用户的启动地址 //print("taskexits %p\n", t); taskexit(0); //print("not reacehd\n"); }
void taskmain(int argc, char* argv[]) { char buf[100]; //HANDLE ev = CreateEvent(0, TRUE, FALSE, 0); FD* h = taskopen(_T("D:\\Tracer.java"), GENERIC_READ, 0, OPEN_EXISTING, 0); if (h == 0) { puts("f****d"); abort(); } //handlewait(ev); while (1) { if (fdread(h, buf, 99) == -1) { abort(); } buf[99] = '\0'; puts(buf); } /* if (fdread(h, buf, 100) == -1) { abort(); } buf[99] = '\0'; puts(buf);*/ taskexit(0); //taskcreate(test, 0, 32768); //while (1) //{ // puts("turtles"); // taskdelay(500); // taskyield(); //} }
static void taskmain(ltctx *lt, void *unused) { int i, n; if(argc != 4) { fprintf(stderr, "usage: httpload n server url\n"); fprintf(stderr, " ex: httpload 4 127.0.0.1 /\n"); taskexit(lt, 1); } n = atoi(argv[1]); server = argv[2]; url = argv[3]; for(i=0; i<n; i++) { taskcreate(lt, fetchtask, 0, STACK); while(taskyield(lt) > 1) ; //taskdelay(lt, 1/*ms*/); } }
void Connection_deliver_task(void *v) { Connection *conn=v; bstring msg=NULL; while(1) { msg = Connection_deliver_dequeue(conn); check_debug(msg,"Received NULL msg on FD %d, exiting deliver task",IOBuf_fd(conn->iob)); check(-1 != Connection_deliver_raw_internal(conn,msg),"Error delivering to MSG listener on FD %d, closing them.", IOBuf_fd(conn->iob)); bdestroy(msg); msg=NULL; } error: conn->deliverTaskStatus=DT_DYING; while(conn->deliverPost > conn->deliverAck) { bdestroy(Connection_deliver_dequeue(conn)); } bdestroy(msg); if (IOBuf_fd(conn->iob) >= 0) shutdown(IOBuf_fd(conn->iob), SHUT_RDWR); debug("Deliver Task Shut Down\n"); conn->deliverTaskStatus=DT_DEAD; taskexit(0); }
void taskmain(int argc, char *argv[]) { dbg_set_log(stderr); glob_t profile_glob; int rc = 0; int i = 0; Action *action = NULL; tst_t *targets = NULL; bstring pid_file = NULL; char *procer_error_log = NULL; m2program = procer_program; check(argc == 3, "USAGE: %s <profile_dir> <procer_pid_file>", m2program); pid_file = bfromcstr(argv[2]); srand(time(NULL)); // simple randomness rc = Unixy_remove_dead_pidfile(pid_file); check(rc == 0, "Failed to remove %s, %s is probably already running.", bdata(pid_file), m2program); rc = Unixy_daemonize(1); check(rc == 0, "Couldn't daemonize, that's not good."); rc = chdir(argv[1]); check(rc == 0, "Couldn't change to %s profile dir.", argv[1]); rc = Unixy_pid_file(pid_file); check(rc == 0, "Failed to make the PID file: %s", bdata(pid_file)); if( (procer_error_log = getenv("PROCER_ERROR_LOG")) == NULL) procer_error_log = "error.log"; FILE *log = fopen(procer_error_log, "a+"); check(log, "Couldn't open error.log"); setbuf(log, NULL); dbg_set_log(log); bstring dir_glob = bformat("%s/[A-Za-z0-9]*", argv[1]); check(dir_glob, "Couldn't make the directory glob."); rc = glob(bdata(dir_glob), GLOB_ERR, NULL, &profile_glob); check(rc == 0, "Failed to find directories in the profiles."); struct stat sb; debug("Loading %zu actions.", profile_glob.gl_pathc); start_terminator(); while(RUNNING) { for(i = 0; i < profile_glob.gl_pathc; i++) { rc = lstat(profile_glob.gl_pathv[i], &sb); check(rc == 0, "Failed to stat file or directory: %s", profile_glob.gl_pathv[i]); if (sb.st_mode & S_IFDIR) { action = Action_create(profile_glob.gl_pathv[i]); targets = tst_insert(targets, bdata(action->name), blength(action->name), action); } } // now we setup the dependencies from the settings they've got tst_traverse(targets, Action_dependency_assign, targets); tst_traverse(targets, Action_start_all, NULL); while(RUNNING) { Action_sleep(1); } } log_warn("Exiting as requested from procer."); taskexit(0); error: taskexitall(1); }
// // This is the router for all new incoming connections. The overall flow // for what we're doing here is as follows: // // First, we'll read the request message that comes in off the new connection. // // If a server ID is in the request, we'll attempt to lookup the server task // in the context routing hash table. If the server task exists in the hash // table, we'll create a new connection task and add it to the server's // connection list. // // If the server ID is not in the context's routing hash table, we respond to // the new connection with a suggestion to have the client ask the location // quorum where the server may be located at. If possible, we should send the // address and port number of the last known location quorum leader (or any // location quorum member if the leader is not known). // // If the client doesn't send a server ID at all, we'll then try to determine // what the client wants to do. The remaining options to attempt at this point // are the following: // // 1. Become a client-server instance. // 2. Respond with the address and port of the location quorum leader (or a // location quorum member if the leader is not known). // 3. Create a new location quorum by becoming a location quorum leader. // void TDB_routing_task(TDB_router_t* router) { TDB_msg_client_control_t control_msg_data; char new_uuid_string[UUID_STR_LEN]; uuid_t new_uuid; TDB_replica_t* new_replica; taskname("router"); if(TDB_proto_handle_connect_msg(router->accept_fd) != TDB_SUCCESS) { LOG(TDB_LOG_ERR, "Did not receive a valid connect message while routing."); taskexit(TDB_ERROR); } if(TDB_proto_receive_control_msg(router->accept_fd, &control_msg_data) != TDB_SUCCESS) { LOG(TDB_LOG_ERR, "Did not receive a valid control message while routing."); taskexit(TDB_ERROR); } else { if(TDB_proto_send_control_resp_msg(router->accept_fd) != TDB_SUCCESS) { LOG(TDB_LOG_ERR, "Failed to send a response to the control message."); taskexit(TDB_ERROR); } else { LOG(TDB_LOG_DBG, "Sent response to control message."); } } switch(control_msg_data.action) { case TDB_PROTO_CTRL_ATTACH_APPEND: case TDB_PROTO_CTRL_ATTACH_DATA: case TDB_PROTO_CTRL_ATTACH_VOTE: if(TDB_replica_attach(router, control_msg_data.uuid, control_msg_data.action) != TDB_SUCCESS) { uuid_unparse(control_msg_data.uuid, new_uuid_string); LOG(TDB_LOG_ERR, "Failed to attach to UUID `%s'.", new_uuid_string); } else { LOG(TDB_LOG_DBG, "Attach completed."); } break; case TDB_PROTO_CTRL_PROXY: LOG(TDB_LOG_DBG, "Handling control proxy message."); LOG(TDB_LOG_ERR, "Not implemented yet."); break; case TDB_PROTO_CTRL_FOLLOWER: LOG(TDB_LOG_DBG, "Handling control follower message."); LOG(TDB_LOG_ERR, "Not implemented yet."); break; case TDB_PROTO_CTRL_LEADER: TDB_replica_init(&new_replica); if(TDB_bootstrap_leader(new_replica, router->ctx, \ &new_uuid, control_msg_data.path) == TDB_SUCCESS) { uuid_unparse(new_uuid, new_uuid_string); LOG(TDB_LOG_ERR, "Quorum leader created with UUID `%s'.", new_uuid_string); //TODO: return uuid to requestor? } else { LOG(TDB_LOG_ERR, "Failed to bootstrap a quorum leader."); } break; case TDB_PROTO_CTRL_LOCATION: TDB_replica_init(&new_replica); if(TDB_bootstrap_location(new_replica, router->ctx, \ &new_uuid) == TDB_SUCCESS) { uuid_unparse(new_uuid, new_uuid_string); LOG(TDB_LOG_ERR, "Location quorum leader created with UUID `%s'.", new_uuid_string); //TODO: return uuid to requestor? } else { LOG(TDB_LOG_ERR, "Failed to bootstrap a location quorum leader."); } break; case TDB_PROTO_CTRL_EXIT: LOG(TDB_LOG_DBG, "Handling control exit message."); LOG(TDB_LOG_ERR, "Not implemented yet."); break; case TDB_PROTO_CTRL_DESTROY: LOG(TDB_LOG_DBG, "Handling control destroy message."); LOG(TDB_LOG_ERR, "Not implemented yet."); break; default: LOG(TDB_LOG_ERR, "Encountered unrecognized control message type of `%d'.", \ control_msg_data.action); taskexit(TDB_ERROR); } LOG(TDB_LOG_DBG, "Completed routing. Exiting task."); TDB_free_router(router); taskexit(TDB_SUCCESS); }