void* _server_worker (void *args) { assert (args != NULL); // get data and free it worker_arg_t *p = (worker_arg_t *)args; server_t *server = p->server; int sd = p->sd; free (args); // get log zlog_category_t *category = zlog_get_category("server"); zlog_debug (category, "Worker: serve descripter %d.", sd); // producer shutdown signal boolean producer_shutdown = false; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // worker id unsigned int worker_id = pthread_self (); // loop while (server->shutdown == false) { // block and read request_t request; int status = _read_request (sd, &request); // update sd request.client_sd = sd; // client closed if (status == 0) { zlog_info (category, "Client at %d closed.", sd); producer_shutdown = true; pthread_mutex_lock (&mutex); pthread_mutex_unlock (&mutex); close (sd); break; } assert (status == sizeof (request_t)); // debug char tmp[256]; encode_req (&request, tmp); zlog_info (category, "REQUEST RECEIVED: %s", tmp); // deal with NOT_EXIST if (_check_movie (&request, server) == false) { response_t response; memcpy (&response.request, &request, sizeof (request_t)); response.worker_id = pthread_self (); response.data = malloc ((strlen (MSG_NOT_EXIST) + 1) * sizeof (char)); strcpy (response.data, MSG_NOT_EXIST); response.len = strlen (MSG_NOT_EXIST) + 1; // block and write _write_response (sd, (void *)&response); // free free (response.data); break; } // malloc here, free at _producer producer_arg_t *arg = (producer_arg_t *)malloc (sizeof (producer_arg_t)); assert (arg != NULL); memset (arg, 0, sizeof (producer_arg_t)); // setup arg->server = server; arg->worker_id = worker_id; memcpy (&arg->request, &request, sizeof (request_t)); arg->shutdown = &producer_shutdown; arg->mutex = &mutex; // decode command if (strcmp (request.request, REQ_START) == 0) { // start a movie // shutdown previous producer producer_shutdown = true; pthread_mutex_lock (&mutex); pthread_mutex_unlock (&mutex); producer_shutdown = false; // start from 1 arg->request.frame_number = 1; producer_shutdown = false; // submit server->cluster.submit (&server->cluster, _server_producer, (void *)arg); } else if (strcmp (request.request, REQ_SEEK) == 0) { // shutdown previous producer producer_shutdown = true; pthread_mutex_lock (&mutex); pthread_mutex_unlock (&mutex); producer_shutdown = false; arg->request.frame_number = request.frame_number; // submit server->cluster.submit (&server->cluster, _server_producer, (void *)arg); } else if (strcmp (request.request, REQ_STOP) == 0) { producer_shutdown = true; } else { // command not supported assert (false); } } pthread_mutex_destroy (&mutex); }
void HttpHandler::start_handle() { printf("start handler http\n"); sock_file_ = fdopen(http_fd_,"a+"); if (NULL == sock_file_) _clear_data(); //read first line of HTTP METHOD _read_request(); //read option for (int i = 0; i < MAX_HTTP_FIELD_PAIR_NUM; i++) { if (http_arg_info_[i].key) printf("%s\t:\t%s\n",http_arg_info_[i].key,http_arg_info_[i].value); } //read till \r\n,empty line while (fgets(http_option_data_,MAX_HTTP_LINE_SIZE,sock_file_) && strcmp(http_option_data_,"\r\n") == 0) { printf("%s\n",http_option_data_); memset(&http_option_data_[0],0,MAX_HTTP_LINE_SIZE); } if (pipe(handle_in_pipe_) < 0 || pipe(handle_out_pipe_) < 0) _clear_data(); int pid = fork(); if (pid < 0) _clear_data(); if (pid == 0) { // close(handle_in_pipe_[0]); close(handle_out_pipe_[1]); dup2(handle_in_pipe_[1],1); //associate wr-pipe with stdout dup2(handle_out_pipe_[0],0); //associate rd-pipe with stdin //set up env char env_buff[MAX_HTTP_FIELD_VALUE_LEN]; for (int i = 0; i < MAX_HTTP_FIELD_PAIR_NUM; i++) { if (http_arg_info_[i].key) { memset(&env_buff[0],0,sizeof(env_buff)); sprintf(env_buff,"%s=%s",http_arg_info_[i].key,http_arg_info_[i].value); putenv(&env_buff[0]); // fprintf(stderr,"get env %s\t%s",http_arg_info_[i].key,getenv(http_arg_info_[i].key)); } } if (execl("./cgi.sh","test",NULL) < 0) printf("can not load exe file,please check the excute previlege"); } else if (pid > 0 ) { close(handle_in_pipe_[1]); close(handle_out_pipe_[0]); //handle data //only for read char rdchar; while (read(handle_in_pipe_[0],&rdchar,1)) fwrite(&rdchar,1,1,sock_file_); //release fd close(handle_in_pipe_[0]); close(handle_out_pipe_[1]); //waiting for child process exit int status = 0; waitpid(pid, &status, 0); _clear_data(); } }