static void test_num1(t_test *test) { t_job *job21; t_job *job42; t_job *job84; t_lst *jobs = shenv_singleton()->jobs; twl_lst_clear(jobs, job_del_void); job21 = job_new(1, twl_lst_new()); job21->job_id = 21; job42 = job_new(2, twl_lst_new()); job42->job_id = 42; job84 = job_new(3, twl_lst_new()); job84->job_id = 84; twl_lst_push_back(jobs, job21); twl_lst_push_back(jobs, job42); twl_lst_push_back(jobs, job84); mt_assert(job_mgr_find_by_job_id(jobs, "21")->job_id == 21); mt_assert(job_mgr_find_by_job_id(jobs, "42")->job_id == 42); mt_assert(job_mgr_find_by_job_id(jobs, "84")->job_id == 84); mt_assert(job_mgr_find_by_job_id(jobs, "100") == NULL); mt_assert(job_mgr_find_by_job_id(jobs, "+")->job_id == 84); mt_assert(job_mgr_find_by_job_id(jobs, "-")->job_id == 42); mt_assert(job_mgr_find_by_job_id(jobs, "0") == NULL); mt_assert(job_mgr_find_by_job_id(jobs, "x") == NULL); twl_lst_clear(jobs, job_del_void); }
/** * \brief get a pointer to the current Job struct * * @return a pointer to the current job struct. If a Job had not been * initialized before, it will be initialized now. */ Job * xvc_job_ptr (void) { if (job == NULL) job_new (); return (job); }
uint32_t job_serv_write(void (*callback)(uint8_t status,void *extra),void *extra,int sock,const uint8_t *packet,uint32_t length) { jobpool* jp = globalpool; chunk_rw_args *args; args = malloc(sizeof(chunk_rw_args)); passert(args); args->sock = sock; args->packet = packet; args->length = length; return job_new(jp,OP_SERV_WRITE,args,callback,extra); }
uint32_t job_get_chunk_blocks(void (*callback)(uint8_t status,void *extra),void *extra,uint64_t chunkid,uint32_t version,uint8_t *blocks) { jobpool* jp = globalpool; chunk_ij_args *args; args = malloc(sizeof(chunk_ij_args)); passert(args); args->chunkid = chunkid; args->version = version; args->pointer = blocks; return job_new(jp,OP_GETBLOCKS,args,callback,extra); }
uint32_t job_get_chunk_checksum_tab(void (*callback)(uint8_t status,void *extra),void *extra,uint64_t chunkid,uint32_t version,uint8_t *checksum_tab) { jobpool* jp = globalpool; chunk_ij_args *args; args = malloc(sizeof(chunk_ij_args)); passert(args); args->chunkid = chunkid; args->version = version; args->pointer = checksum_tab; return job_new(jp,OP_GETCHECKSUMTAB,args,callback,extra); }
void request_jobs_iterate( Request *t, int (*callback)(const Job *j, void *user_data), void *user_data) { int i; for (i = 0; i < t->queue.count-1; ) { int cmd = t->queue.elements[i++]; Id id = t->queue.elements[i++]; if (callback( job_new( t->pool, cmd, id ), user_data ) ) break; } }
Job * request_job_get( Request *t, int i ) { int size, cmd; Id id; i <<= 1; size = t->queue.count; if (i-1 >= size) return NULL; cmd = t->queue.elements[i]; id = t->queue.elements[i+1]; return job_new( t->pool, cmd, id ); }
uint32_t job_chunkop(void (*callback)(uint8_t status,void *extra),void *extra,uint64_t chunkid,uint32_t version,uint32_t newversion,uint64_t copychunkid,uint32_t copyversion,uint32_t length) { jobpool* jp = globalpool; chunk_op_args *args; args = malloc(sizeof(chunk_op_args)); passert(args); args->chunkid = chunkid; args->version = version; args->newversion = newversion; args->copychunkid = copychunkid; args->copyversion = copyversion; args->length = length; return job_new(jp,OP_CHUNKOP,args,callback,extra); }
char * solutionelemen_string( const SolutionElement *se ) { #if 0 switch (se->p) { case SOLVER_SOLUTION_INFARCH: to_string("Install %s", solvable_ return job_new( pool, SOLVER_INSTALL|SOLVER_SOLVABLE, se->rp ); break; case SOLVER_SOLUTION_DISTUPGRADE: return job_new( pool, SOLVER_INSTALL|SOLVER_SOLVABLE, se->rp ); break; case SOLVER_SOLUTION_JOB: return request_job_get( problem->request, se->rp); break; default: } return job_new( pool, SOLVER_INSTALL|SOLVER_SOLVABLE, se->rp ); #endif return to_string("SolutionElement %p", se); } int solutionelement_cause( const SolutionElement *se ) { if (se->p > 0) return 0; else return se->p - 1; } Job * solutionelement_job( const SolutionElement *se ) { const Problem *problem = se->solution->problem; Pool *pool = problem->solver->pool; #if SATSOLVER_VERSION > 1300 switch (se->p) { case SOLVER_SOLUTION_INFARCH: return job_new( pool, SOLVER_INSTALL|SOLVER_SOLVABLE, se->rp ); break; case SOLVER_SOLUTION_DISTUPGRADE: return job_new( pool, SOLVER_INSTALL|SOLVER_SOLVABLE, se->rp ); break; case SOLVER_SOLUTION_JOB: return request_job_get( problem->request, se->rp); break; } #else return NULL; #endif return job_new( pool, SOLVER_INSTALL|SOLVER_SOLVABLE, se->rp ); }
int avahi_llmnr_query_scheduler_post(AvahiLLMNRQueryScheduler *s, AvahiLLMNRQuery *lq, int immediately) { AvahiLLMNRQueryJob *qj; struct timeval tv; assert(s); assert(lq); if (!(qj = job_new(s, lq))) return 0; qj->time_event = avahi_time_event_new(s->time_event_queue, avahi_elapse_time(&tv, 0, immediately ? 0 : AVAHI_LLMNR_JITTER), elapse_timeout_callback, qj); return 1; }
uint32_t job_replicate_raid(void (*callback)(uint8_t status,void *extra),void *extra,uint64_t chunkid,uint32_t version,uint8_t srccnt,const uint32_t xormasks[4],const uint8_t *srcs) { jobpool* jp = globalpool; chunk_rp_args *args; uint8_t *ptr; ptr = malloc(sizeof(chunk_rp_args)+srccnt*18); passert(ptr); args = (chunk_rp_args*)ptr; ptr += sizeof(chunk_rp_args); args->chunkid = chunkid; args->version = version; args->srccnt = srccnt; args->xormasks[0] = xormasks[0]; args->xormasks[1] = xormasks[1]; args->xormasks[2] = xormasks[2]; args->xormasks[3] = xormasks[3]; memcpy(ptr,srcs,srccnt*18); return job_new(jp,OP_REPLICATE,args,callback,extra); }
uint32_t job_replicate_simple(void (*callback)(uint8_t status,void *extra),void *extra,uint64_t chunkid,uint32_t version,uint32_t ip,uint16_t port) { jobpool* jp = globalpool; chunk_rp_args *args; uint8_t *ptr; ptr = malloc(sizeof(chunk_rp_args)+18); passert(ptr); args = (chunk_rp_args*)ptr; ptr += sizeof(chunk_rp_args); args->chunkid = chunkid; args->version = version; args->srccnt = 1; args->xormasks[0] = UINT32_C(0x88888888); args->xormasks[1] = UINT32_C(0x44444444); args->xormasks[2] = UINT32_C(0x22222222); args->xormasks[3] = UINT32_C(0x11111111); put64bit(&ptr,chunkid); put32bit(&ptr,version); put32bit(&ptr,ip); put16bit(&ptr,port); return job_new(jp,OP_REPLICATE,args,callback,extra); }
struct task *task_new(struct parsed *prog) { extern struct task *tasks; struct task *t, *thistask; struct job *jprev = NULL; struct parsed *iter; int jid = 1; for(t = tasks; t; t = t->next){ struct job *j; for(j = t->jobs; j; j = j->next) if(j->job_id == jid){ jid++; t = tasks; break; } } thistask = umalloc(sizeof *thistask); memset(thistask, 0, sizeof *thistask); thistask->state = TASK_BEGIN; for(iter = prog; iter; iter = iter->next){ struct job *j = job_new(iter->argvp, jid, iter->redir); if(jprev) jprev->next = j; else thistask->jobs = j; jprev = j; } jprev->next = NULL; thistask->cmd = task_desc(thistask); return thistask; }
int avahi_query_scheduler_post(AvahiQueryScheduler *s, AvahiKey *key, int immediately, unsigned *ret_id) { struct timeval tv; AvahiQueryJob *qj; assert(s); assert(key); if ((qj = find_history_job(s, key))) return 0; avahi_elapse_time(&tv, immediately ? 0 : AVAHI_QUERY_DEFER_MSEC, 0); if ((qj = find_scheduled_job(s, key))) { /* Duplicate questions suppression */ if (avahi_timeval_compare(&tv, &qj->delivery) < 0) { /* If the new entry should be scheduled earlier, * update the old entry */ qj->delivery = tv; avahi_time_event_update(qj->time_event, &qj->delivery); } qj->n_posted++; } else { if (!(qj = job_new(s, key, 0))) return 0; /* OOM */ qj->delivery = tv; qj->time_event = avahi_time_event_new(s->time_event_queue, &qj->delivery, elapse_callback, qj); } if (ret_id) *ret_id = qj->id; return 1; }
void avahi_response_scheduler_suppress(AvahiResponseScheduler *s, AvahiRecord *record, const AvahiAddress *querier) { AvahiResponseJob *rj; assert(s); assert(record); assert(querier); if ((rj = find_scheduled_job(s, record))) { if (rj->querier_valid && avahi_address_cmp(querier, &rj->querier) == 0 && /* same originator */ avahi_record_is_goodbye(record) == avahi_record_is_goodbye(rj->record) && /* both goodbye packets, or both not */ record->ttl >= rj->record->ttl/2) { /* sensible TTL */ /* A matching entry was found, so let's drop it */ /* avahi_log_debug("Known answer suppression active!"); */ job_free(s, rj); } } if ((rj = find_suppressed_job(s, record, querier))) { /* Let's update the old entry */ avahi_record_unref(rj->record); rj->record = avahi_record_ref(record); } else { /* Create a new entry */ if (!(rj = job_new(s, record, AVAHI_SUPPRESSED))) return; /* OOM */ rj->querier_valid = 1; rj->querier = *querier; } gettimeofday(&rj->delivery, NULL); job_set_elapse_time(s, rj, AVAHI_RESPONSE_SUPPRESS_MSEC, 0); }
void avahi_response_scheduler_incoming(AvahiResponseScheduler *s, AvahiRecord *record, int flush_cache) { AvahiResponseJob *rj; assert(s); /* This function is called whenever an incoming response was * receieved. We drop scheduled responses which match here. The * keyword is "DUPLICATE ANSWER SUPPRESION". */ if ((rj = find_scheduled_job(s, record))) { if ((!rj->flush_cache || flush_cache) && /* flush cache bit was set correctly */ avahi_record_is_goodbye(record) == avahi_record_is_goodbye(rj->record) && /* both goodbye packets, or both not */ record->ttl >= rj->record->ttl/2) { /* sensible TTL */ /* A matching entry was found, so let's mark it done */ /* avahi_log_debug("Response suppressed by distributed duplicate suppression"); */ job_mark_done(s, rj); } return; } if ((rj = find_history_job(s, record))) { /* Found a history job, let's update it */ avahi_record_unref(rj->record); rj->record = avahi_record_ref(record); } else /* Found no existing history job, so let's create a new one */ if (!(rj = job_new(s, record, AVAHI_DONE))) return; /* OOM */ rj->flush_cache = flush_cache; rj->querier_valid = 0; gettimeofday(&rj->delivery, NULL); job_set_elapse_time(s, rj, AVAHI_RESPONSE_HISTORY_MSEC, 0); }
int avahi_probe_scheduler_post(AvahiProbeScheduler *s, AvahiRecord *record, int immediately) { AvahiProbeJob *pj; struct timeval tv; assert(s); assert(record); assert(!avahi_key_is_pattern(record->key)); if ((pj = find_history_job(s, record))) return 0; avahi_elapse_time(&tv, immediately ? 0 : AVAHI_PROBE_DEFER_MSEC, 0); if ((pj = find_scheduled_job(s, record))) { if (avahi_timeval_compare(&tv, &pj->delivery) < 0) { /* If the new entry should be scheduled earlier, update the old entry */ pj->delivery = tv; avahi_time_event_update(pj->time_event, &pj->delivery); } return 1; } else { /* Create a new job and schedule it */ if (!(pj = job_new(s, record, 0))) return 0; /* OOM */ pj->delivery = tv; pj->time_event = avahi_time_event_new(s->time_event_queue, &pj->delivery, elapse_callback, pj); /* avahi_log_debug("Accepted new probe job."); */ return 1; } }
void avahi_query_scheduler_incoming(AvahiQueryScheduler *s, AvahiKey *key) { AvahiQueryJob *qj; assert(s); assert(key); /* This function is called whenever an incoming query was * received. We drop scheduled queries that match. The keyword is * "DUPLICATE QUESTION SUPPRESION". */ if ((qj = find_scheduled_job(s, key))) { job_mark_done(s, qj); return; } /* Look if there's a history job for this key. If there is, just * update the elapse time */ if (!(qj = find_history_job(s, key))) if (!(qj = job_new(s, key, 1))) return; /* OOM */ gettimeofday(&qj->delivery, NULL); job_set_elapse_time(s, qj, AVAHI_QUERY_HISTORY_MSEC, 0); }
int avahi_response_scheduler_post(AvahiResponseScheduler *s, AvahiRecord *record, int flush_cache, const AvahiAddress *querier, int immediately) { AvahiResponseJob *rj; struct timeval tv; /* char *t; */ assert(s); assert(record); assert(!avahi_key_is_pattern(record->key)); /* t = avahi_record_to_string(record); */ /* avahi_log_debug("post %i %s", immediately, t); */ /* avahi_free(t); */ /* Check whether this response is suppressed */ if (querier && (rj = find_suppressed_job(s, record, querier)) && avahi_record_is_goodbye(record) == avahi_record_is_goodbye(rj->record) && rj->record->ttl >= record->ttl/2) { /* avahi_log_debug("Response suppressed by known answer suppression."); */ return 0; } /* Check if we already sent this response recently */ if ((rj = find_history_job(s, record))) { if (avahi_record_is_goodbye(record) == avahi_record_is_goodbye(rj->record) && rj->record->ttl >= record->ttl/2 && (rj->flush_cache || !flush_cache)) { /* avahi_log_debug("Response suppressed by local duplicate suppression (history)"); */ return 0; } /* Outdated ... */ job_free(s, rj); } avahi_elapse_time(&tv, immediately ? 0 : AVAHI_RESPONSE_DEFER_MSEC, immediately ? 0 : AVAHI_RESPONSE_JITTER_MSEC); if ((rj = find_scheduled_job(s, record))) { /* avahi_log_debug("Response suppressed by local duplicate suppression (scheduled)"); */ /* Update a little ... */ /* Update the time if the new is prior to the old */ if (avahi_timeval_compare(&tv, &rj->delivery) < 0) { rj->delivery = tv; avahi_time_event_update(rj->time_event, &rj->delivery); } /* Update the flush cache bit */ if (flush_cache) rj->flush_cache = 1; /* Update the querier field */ if (!querier || (rj->querier_valid && avahi_address_cmp(querier, &rj->querier) != 0)) rj->querier_valid = 0; /* Update record data (just for the TTL) */ avahi_record_unref(rj->record); rj->record = avahi_record_ref(record); return 1; } else { /* avahi_log_debug("Accepted new response job."); */ /* Create a new job and schedule it */ if (!(rj = job_new(s, record, AVAHI_SCHEDULED))) return 0; /* OOM */ rj->delivery = tv; rj->time_event = avahi_time_event_new(s->time_event_queue, &rj->delivery, elapse_callback, rj); rj->flush_cache = flush_cache; if ((rj->querier_valid = !!querier)) rj->querier = *querier; return 1; } }
/** * \brief set the Job's contents from the current preferences * * @param app the preferences struct to set the Job from */ void xvc_job_set_from_app_data (XVC_AppData * app) { XVC_CapTypeOptions *cto; char file[PATH_MAX + 1]; // make sure we do have a job if (!job) { job_new (); } // switch sf or mf if (app->current_mode != 0) cto = &(app->multi_frame); else cto = &(app->single_frame); // various manual settings // need to have the flags set to smth. before other functions try to // do: flags |= or smth. job->flags = app->flags; if (app->current_mode == 0 || xvc_is_filename_mutable (cto->file)) job->flags &= ~(FLG_AUTO_CONTINUE); job->time_per_frame = (int) (1000 / ((float) cto->fps.num / (float) cto->fps.den)); job->state = VC_STOP; // FIXME: better move this outta here? job->pic_no = cto->start_no; job->movie_no = 0; // FIXME: make this configurable if (cto->audioWanted != 0) job->flags |= FLG_REC_SOUND; else job->flags &= ~FLG_REC_SOUND; job_set_sound_dev (app->snddev, cto->sndrate, cto->sndsize, cto->sndchannels); job->target = cto->target; if (job->target <= 0) { if (job->target == 0) { // we should be able to safely assume cto->filename is longer // smaller than 0 for the next bit because with target == 0 // it would have been set to a default value otherwise job->target = xvc_codec_get_target_from_filename (cto->file); // we assume job->target can never be == 0 now, because a // sanity checking function should have checked before if // we have a valid specification for a target either // through target itself or the filename extension if (job->target <= 0) { fprintf (stderr, "Unrecoverable error while initializing job from app_data.\n"); fprintf (stderr, "targetCodec is still 0. This should never happen.\n"); fprintf (stderr, "Please contact the xvidcap project team.\n"); exit (1); } } } job->targetCodec = cto->targetCodec; if (job->targetCodec <= 0) { if (job->targetCodec == 0) job->targetCodec = xvc_formats[job->target].def_vid_codec; if (job->targetCodec < 0) { fprintf (stderr, "Unrecoverable error while initializing job from app_data.\n"); fprintf (stderr, "targetCodec is still < 0. This should never happen.\n"); fprintf (stderr, "Please contact the xvidcap project team.\n"); exit (1); } } job->au_targetCodec = cto->au_targetCodec; if (job->au_targetCodec <= 0) { if (job->au_targetCodec == 0) job->au_targetCodec = xvc_formats[job->target].def_au_codec; // if 0 the format has no default audio codec. This should only be // the case if the format does not support audio or recording // without audio is encouraged if (job->au_targetCodec < 0) { fprintf (stderr, "Unrecoverable error while initializing job from app_data.\n"); fprintf (stderr, "au_targetCodec is still < 0. This should never happen.\n"); fprintf (stderr, "Please contact the xvidcap project team.\n"); exit (1); } } // set temporary filename if set to "ask-user" if (strlen (cto->file) < 1) { char *home = NULL; int pid; home = getenv ("HOME"); pid = (int) getpid (); snprintf (file, (PATH_MAX + 1), "%s/.xvidcap-tmp.%i.%s", home, pid, xvc_formats[job->target].extensions[0]); } else { snprintf (file, (PATH_MAX + 1), "%s", cto->file); } /** \todo double I need a strdup here? */ job->file = strdup (file); job_set_capture (); // the order of the following actions is key! // the default is to use the colormap of the root window xvc_job_set_save_function (job->target); xvc_job_set_colors (); }
/* evaluate a pipeline (3.9.2) * ----------------------------------------------------------------------- */ int eval_pipeline(struct eval *e, struct npipe *npipe) { struct job *job; union node *node; struct fdstack st; unsigned int n; int pid = 0; int prevfd = -1; int status = -1; /* job = (e->flags & E_JCTL) ? job_new(npipe->ncmd) : NULL;*/ job = job_new(npipe->ncmd); if(job == NULL) { buffer_puts(fd_err->w, "no job control"); buffer_putnlflush(fd_err->w); } for(node = npipe->cmds; node; node = node->list.next) { fdstack_push(&st); /* if there was a previous command we read input from pipe */ if(prevfd >= 0) { struct fd *in; fd_alloca(in); fd_push(in, STDIN_FILENO, FD_READ|FD_PIPE); fd_setfd(in, prevfd); } /* if it isn't the last command we have to create a pipe to pass output to the next command */ if(node->list.next) { struct fd *out; fd_alloca(out); fd_push(out, STDOUT_FILENO, FD_WRITE|FD_PIPE); prevfd = fd_pipe(out); if(prevfd == -1) { close(prevfd); sh_error("pipe creation failed"); } } if((n = fdstack_npipes(FD_HERE|FD_SUBST))) fdstack_pipe(n, fdstack_alloc(n)); pid = job_fork(job, node, npipe->bgnd); if(!pid) { /* no job control for commands inside pipe */ /* e->mode &= E_JCTL;*/ /* exit after evaluating this subtree */ exit(eval_tree(e, node, E_EXIT)); } fdstack_pop(&st); fdstack_data(); } if(!npipe->bgnd) { job_wait(job, 0, &status, 0); } /* if(job) shell_free(job);*/ return WEXITSTATUS(status); }
/**************************************************************************** Message Handler: submit_job_*(func, uniq, arg) ****************************************************************************/ int msg_submit_job(Client *cli, unsigned char *arg, int argsize, gboolean background, gboolean high) { unsigned char *args[3]; int last_arg_len = parse_args(args, 3, arg, argsize); int is_uniq = args[1][0] != 0; const gchar *func = g_intern_string((char*)args[0]); // printf(">> [%s] = %.8x\n", args[0], func); /* look for a duplicate job - if one exists, add to listeners */ if (is_uniq) { UniqJobKey uk; uk.func = func; if (args[1][0] == '-' && args[1][1] == 0) { uk.uniq = args[2]; uk.uniq_len = last_arg_len; } else { uk.uniq = args[1]; uk.uniq_len = strlen((char*)args[1]); } Job *job = g_hash_table_lookup(g_uniq_jobs, &uk); if (job) { #if DEBUG g_debug("[%s] submit_job - merging %s:%s -> %s", cli->id, job->func, job->uniq, job->handle); #endif if (!job->background) { g_ptr_array_add_uniq(job->listeners, cli); client_listen_to(cli, job); } MemBlock *block = new_response(MSG_JOB_CREATED, strlen(job->handle), (unsigned char *)job->handle); client_send(cli, block); return 0; } } Job *job = job_new(); generate_job_handle(job->handle); job->func = func; if (last_arg_len == 0) job->arg = (unsigned char *)""; else { job->arg = malloc(last_arg_len); memcpy(job->arg, args[2], last_arg_len); } job->arg_len = last_arg_len; job->background = background; if (!background) { g_ptr_array_add(job->listeners, cli); } g_hash_table_insert(g_jobs, job->handle, job); #if DEBUG g_debug("[%s] submit_job: %s, %s -> %s", cli->id, args[0], args[1], job->handle); #endif jobqueue_push(g_jobqueue, job, high); if (!background) { client_listen_to(cli, job); } job->is_uniq = is_uniq; if (is_uniq) { job->uniq = strdup((char*)args[1]); job->uniq_key.func = func; if (job->uniq[0] == '-' && job->uniq[1] == 0) { job->uniq_key.uniq = job->arg; job->uniq_key.uniq_len = job->arg_len; } else { job->uniq_key.uniq = (unsigned char *)job->uniq; job->uniq_key.uniq_len = strlen(job->uniq); } g_hash_table_insert(g_uniq_jobs, &job->uniq_key, job); #if DEBUG g_debug("[%s] \tadded uniq job %s", cli->id, job->handle); #endif } MemBlock *block = new_response(MSG_JOB_CREATED, strlen(job->handle), (unsigned char *)job->handle); client_send(cli, block); wake_up_sleepers(job->func); return 0; }
static job_t * job_from_command_line(const char *command_line, char *envp[]) { job_t *job; char *work_copy, *history_copy; char *cmds[MAX_TOKEN]; int n_cmds; int argc; char *argv_buf[MAX_TOKEN]; int i; char *tmp_string; work_copy = strdup(string_command_trim_start(command_line)); string_command_trim_end(work_copy); n_cmds = string_command_tokenize(work_copy, cmds, "|"); /* printf("n_cmds = %d\n", n_cmds); */ if (n_cmds == 0) { return NULL; } history_copy = strdup(string_command_trim_start(command_line)); string_command_trim_end(history_copy); history_add(history_copy); /* printf("HISTORYCOPY = %s\n", history_copy); */ if (n_cmds == 1) { char *builtin_copy = strdup(cmds[0]); boolean is_builtin; argc = string_command_tokenize(builtin_copy, argv_buf, " \t"); is_builtin = builtin_handle(argc, argv_buf, envp); free(builtin_copy); if (is_builtin) return NULL; } /* TODO: store in the history, and free */ job = job_new(history_copy); job_set_bg(job, string_command_bg(work_copy)); tmp_string = string_command_write_to(cmds[n_cmds - 1]); if (tmp_string) { tmp_string = string_command_trim(tmp_string); job_set_stdout(job, tmp_string); } tmp_string = string_command_read_from(cmds[0]); if (tmp_string) { tmp_string = string_command_trim(tmp_string); job_set_stdin(job, tmp_string); } for (i = 0; i < n_cmds; i++) { argc = string_command_tokenize(cmds[i], argv_buf, " \t"); job_add_program(job, argv_buf[0], argc, argv_buf, envp); } free(work_copy); return job; }
int main (int argc, char *argv[]) { HTTPMgmt *httpmgmt; HTTPStreaming *httpstreaming; GMainLoop *loop; GOptionContext *ctx; GError *err = NULL; gboolean foreground; struct rlimit rlim; GDateTime *datetime; gchar exe_path[512], *date; ctx = g_option_context_new (NULL); g_option_context_add_main_entries (ctx, options, NULL); g_option_context_add_group (ctx, gst_init_get_option_group ()); if (!g_option_context_parse (ctx, &argc, &argv, &err)) { g_print ("Error initializing: %s\n", GST_STR_NULL (err->message)); exit (1); } g_option_context_free (ctx); GST_DEBUG_CATEGORY_INIT (GSTREAMILL, "gstreamill", 0, "gstreamill log"); if (version) { print_version_info (); exit (0); } /* stop gstreamill. */ if (stop) { gchar *pid_str; gint pid; g_file_get_contents (PID_FILE, &pid_str, NULL, NULL); if (pid_str == NULL) { g_print ("File %s not found, check if gstreamill is running.\n", PID_FILE); exit (1); } pid = atoi (pid_str); g_free (pid_str); g_print ("stoping gstreamill with pid %d ...\n", pid); kill (pid, SIGTERM); exit (0); } /* readlink exe path before setuid, on CentOS, readlink exe path after setgid/setuid failure on permission denied */ memset (exe_path, '\0', sizeof (exe_path)); if (readlink ("/proc/self/exe", exe_path, sizeof (exe_path)) == -1) { g_print ("Read /proc/self/exe error: %s", g_strerror (errno)); exit (2); } if (prepare_gstreamill_run_dir () != 0) { g_print ("Can't create gstreamill run directory\n"); exit (3); } /* if (set_user_and_group () != 0) { g_print ("set user and group failure\n"); exit (4); } */ if (job_file != NULL) { /* gstreamill command with job, run in foreground */ foreground = TRUE; } else { /* gstreamill command without job, run in background */ foreground = FALSE; } if (gst_debug_get_default_threshold () < GST_LEVEL_WARNING) { gst_debug_set_default_threshold (GST_LEVEL_WARNING); } /* initialize ts segment static plugin */ if (!gst_plugin_register_static (GST_VERSION_MAJOR, GST_VERSION_MINOR, "tssegment", "ts segment plugin", ts_segment_plugin_init, "0.1.0", "GPL", "GStreamer", "GStreamer", "http://gstreamer.net/")) { GST_ERROR ("registe tssegment error"); exit (17); } /* subprocess, create_job_process */ if (shm_name != NULL) { gint fd; gchar *job_desc, *p; Job *job; gchar *log_path, *name; gint ret; /* set subprocess maximum of core file */ rlim.rlim_cur = 0; rlim.rlim_max = 0; if (setrlimit (RLIMIT_CORE, &rlim) == -1) { GST_ERROR ("setrlimit error: %s", g_strerror (errno)); } /* read job description from share memory */ job_desc = NULL; fd = shm_open (shm_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if (ftruncate (fd, job_length) == -1) { exit (5); } p = mmap (NULL, job_length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); job_desc = g_strdup (p); if ((job_desc != NULL) && (!jobdesc_is_valid (job_desc))) { exit (6); } /* initialize log */ name = (gchar *)jobdesc_get_name (job_desc); if (!jobdesc_is_live (job_desc)) { gchar *p; p = jobdesc_get_log_path (job_desc); log_path = g_build_filename (p, "gstreamill.log", NULL); g_free (p); } else { log_path = g_build_filename (log_dir, name, "gstreamill.log", NULL); } ret = init_log (log_path); g_free (log_path); if (ret != 0) { exit (7); } /* launch a job. */ datetime = g_date_time_new_now_local (); date = g_date_time_format (datetime, "%b %d %H:%M:%S"); fprintf (_log->log_hd, "\n*** %s : job %s starting ***\n\n", date, name); g_date_time_unref (datetime); g_free (date); job = job_new ("name", name, "job", job_desc, NULL); job->is_live = jobdesc_is_live (job_desc); job->eos = FALSE; loop = g_main_loop_new (NULL, FALSE); GST_INFO ("Initializing job ..."); if (job_initialize (job, TRUE) != 0) { GST_ERROR ("initialize job failure, exit"); exit (8); } GST_INFO ("Initializing job done"); GST_INFO ("Initializing job's encoders output ..."); if (job_encoders_output_initialize (job) != 0) { GST_ERROR ("initialize job encoders' output failure, exit"); exit (8); } GST_INFO ("Initializing job's encoders output done"); GST_INFO ("Starting job ..."); if (job_start (job) != 0) { GST_ERROR ("start livejob failure, exit"); exit (9); } datetime = g_date_time_new_now_local (); date = g_date_time_format (datetime, "%b %d %H:%M:%S"); fprintf (_log->log_hd, "\n*** %s : job %s started ***\n\n", date, name); g_date_time_unref (datetime); g_free (date); g_free (name); g_free (job_desc); signal (SIGPIPE, SIG_IGN); signal (SIGUSR1, sighandler); signal (SIGTERM, stop_job); g_main_loop_run (loop); } else { /* set parent process maximum of core file */ rlim.rlim_cur = RLIM_INFINITY; rlim.rlim_max = RLIM_INFINITY; if (setrlimit (RLIMIT_CORE, &rlim) == -1) { GST_ERROR ("setrlimit error: %s", g_strerror (errno)); } } /* run in background? */ if (!foreground) { gchar *path; gint ret; /* pid file exist? */ if (g_file_test (PID_FILE, G_FILE_TEST_EXISTS)) { g_print ("file %s found, gstreamill already running !!!\n", PID_FILE); exit (10); } /* media directory */ path = g_strdup_printf ("%s/dvr", MEDIA_LOCATION); if (!g_file_test (path, G_FILE_TEST_EXISTS)) { g_printf ("Create DVR directory: %s", path); if (g_mkdir_with_parents (path, 0755) != 0) { g_printf ("Create DVR directory failure: %s", path); } } g_free (path); path = g_strdup_printf ("%s/transcode/in", MEDIA_LOCATION); if (!g_file_test (path, G_FILE_TEST_EXISTS)) { g_printf ("Create transcode directory: %s", path); if (g_mkdir_with_parents (path, 0755) != 0) { g_printf ("Create transcode directory failure: %s", path); } } g_free (path); path = g_strdup_printf ("%s/transcode/out", MEDIA_LOCATION); if (!g_file_test (path, G_FILE_TEST_EXISTS)) { g_printf ("Create transcode directory: %s", path); if (g_mkdir_with_parents (path, 0755) != 0) { g_printf ("Create transcode directory failure: %s", path); } } g_free (path); /* log to file */ path = g_build_filename (log_dir, "gstreamill.log", NULL); ret = init_log (path); g_free (path); if (ret != 0) { g_print ("Init log error, ret %d.\n", ret); exit (11); } /* daemonize */ if (daemon (0, 0) != 0) { fprintf (_log->log_hd, "Failed to daemonize"); remove_pid_file (); exit (1); } /* create pid file */ if (create_pid_file () != 0) { exit (1); } /* customize signal */ signal (SIGUSR1, sighandler); signal (SIGTERM, stop_gstreamill); datetime = g_date_time_new_now_local (); date = g_date_time_format (datetime, "%b %d %H:%M:%S"); fprintf (_log->log_hd, "\n*** %s : gstreamill started ***\n\n", date); g_free (date); g_date_time_unref (datetime); } /* ignore SIGPIPE */ signal (SIGPIPE, SIG_IGN); loop = g_main_loop_new (NULL, FALSE); /* gstreamill */ gstreamill = gstreamill_new ("daemon", !foreground, "log_dir", log_dir, "exe_path", exe_path, NULL); if (gstreamill_start (gstreamill) != 0) { GST_ERROR ("start gstreamill error, exit."); remove_pid_file (); exit (12); } /* httpstreaming, pull */ httpstreaming = httpstreaming_new ("gstreamill", gstreamill, "address", http_streaming, NULL); if (httpstreaming_start (httpstreaming, 10) != 0) { GST_ERROR ("start httpstreaming error, exit."); remove_pid_file (); exit (13); } if (!foreground) { /* run in background, management via http */ httpmgmt = httpmgmt_new ("gstreamill", gstreamill, "address", http_mgmt, NULL); if (httpmgmt_start (httpmgmt) != 0) { GST_ERROR ("start http mangment error, exit."); remove_pid_file (); exit (14); } } else { /* run in foreground, start job */ gchar *job, *p, *result; JSON_Value *val; JSON_Object *obj; /* ctrl-c, stop gstreamill */ signal (SIGINT, stop_gstreamill); /* ctrl-\, stop gstreamill */ signal (SIGQUIT, stop_gstreamill); if (!g_file_get_contents (job_file, &job, NULL, NULL)) { GST_ERROR ("Read job file %s error.", job_file); exit (15); } p = gstreamill_job_start (gstreamill, job); val = json_parse_string (p); obj = json_value_get_object (val); result = (gchar *)json_object_get_string (obj, "result"); GST_INFO ("start job result: %s.", result); if (g_strcmp0 (result, "success") != 0) { exit (16); } json_value_free (val); g_free (p); } g_main_loop_run (loop); return 0; }
static void client_old_parse_messages(GebrCommProtocolSocket * socket, struct client *client) { GList *link; struct gebr_comm_message *message; while ((link = g_list_last(client->socket->protocol->messages)) != NULL) { message = (struct gebr_comm_message *)link->data; /* check login */ if (message->hash == gebr_comm_protocol_defs.ini_def.code_hash) { GList *arguments; GString *accounts_list = g_string_new(""); GString *queue_list = g_string_new(""); GString *display_port = g_string_new(""); /* organize message data */ if ((arguments = gebr_comm_protocol_socket_oldmsg_split(message->argument, 2)) == NULL) goto err; GString *version = g_list_nth_data(arguments, 0); GString *hostname = g_list_nth_data(arguments, 1); g_debug("Current protocol version is: %s", gebr_comm_protocol_get_version()); g_debug("Received protocol version: %s", version->str); if (strcmp(version->str, gebr_comm_protocol_get_version())) { gebr_comm_protocol_socket_oldmsg_send(client->socket, TRUE, gebr_comm_protocol_defs.err_def, 2, "protocol", gebr_comm_protocol_get_version()); goto err; } /* set client info */ client->socket->protocol->logged = TRUE; g_string_assign(client->socket->protocol->hostname, hostname->str); client->server_location = GEBR_COMM_SERVER_LOCATION_REMOTE; const gchar *server_type; if (gebrd_get_server_type() == GEBR_COMM_SERVER_TYPE_MOAB) { /* Get info from the MOAB cluster */ server_moab_read_credentials(accounts_list, queue_list); server_type = "moab"; } else server_type = "regular"; GString *mpi_flavors = g_string_new(""); g_list_foreach(gebrd->mpi_flavors, (GFunc) get_mpi_flavors, mpi_flavors); if (mpi_flavors->len > 0) mpi_flavors = g_string_erase(mpi_flavors, mpi_flavors->len-1, 1); g_debug("------------on daemon, Sending %s", mpi_flavors->str) ; const gchar *model_name; const gchar *cpu_clock; const gchar *total_memory; GebrdCpuInfo *cpuinfo = gebrd_cpu_info_new(); GebrdMemInfo *meminfo = gebrd_mem_info_new(); model_name = gebrd_cpu_info_get (cpuinfo, 0, "model name"); cpu_clock = gebrd_cpu_info_get (cpuinfo, 0, "cpu MHz"); total_memory = gebrd_mem_info_get (meminfo, "MemTotal"); gchar *ncores = g_strdup_printf("%d", gebrd_cpu_info_n_procs(cpuinfo)); gebr_comm_protocol_socket_oldmsg_send(client->socket, FALSE, gebr_comm_protocol_defs.ret_def, 11, gebrd->hostname, server_type, accounts_list->str, model_name, total_memory, gebrd->fs_lock->str, ncores, cpu_clock, gebrd_user_get_daemon_id(gebrd->user), g_get_home_dir(), mpi_flavors->str); gebrd_cpu_info_free(cpuinfo); gebrd_mem_info_free(meminfo); gebr_comm_protocol_socket_oldmsg_split_free(arguments); g_string_free(accounts_list, TRUE); g_string_free(queue_list, TRUE); g_string_free(display_port, TRUE); g_free(ncores); } else if (message->hash == gebr_comm_protocol_defs.gid_def.code_hash) { GList *arguments; /* organize message data */ if ((arguments = gebr_comm_protocol_socket_oldmsg_split(message->argument, 3)) == NULL) goto err; GString *gid = g_list_nth_data(arguments, 0); GString *cookie = g_list_nth_data(arguments, 1); GString *disp_str = g_list_nth_data(arguments, 2); guint display; if (g_strcmp0(disp_str->str, "0") == 0) display = gebr_comm_get_available_port(6010); else display = atoi(disp_str->str); display = MAX(display-6000, 0); g_hash_table_insert(gebrd->display_ports, g_strdup(gid->str), GUINT_TO_POINTER(display)); g_debug("Received gid %s with cookie %s", gid->str, cookie->str); if (cookie->len && gebrd_get_server_type() != GEBR_COMM_SERVER_TYPE_MOAB) { gebrd_message(GEBR_LOG_DEBUG, "Authorizing with system(xauth)"); gchar *tmp = g_strdup_printf(":%d", display); if (!run_xauth_command("add", tmp, cookie->str)) display = 0; g_free(tmp); } gchar *display_str = g_strdup_printf("%d", display ? display + 6000 : 0); gebrd_message(GEBR_LOG_INFO, "Sending port %s to client %s!", display_str, gid->str); gebr_comm_protocol_socket_oldmsg_send(client->socket, FALSE, gebr_comm_protocol_defs.ret_def, 2, gid->str, display_str); g_free(display_str); gebr_comm_protocol_socket_oldmsg_split_free(arguments); } else if (client->socket->protocol->logged == FALSE) { /* not logged! */ goto err; } else if (message->hash == gebr_comm_protocol_defs.qut_def.code_hash) { client_free(client); gebr_comm_message_free(message); return; } else if (message->hash == gebr_comm_protocol_defs.lst_def.code_hash) { job_list(client); } else if (message->hash == gebr_comm_protocol_defs.run_def.code_hash) { GList *arguments; GebrdJob *job; /* organize message data */ if ((arguments = gebr_comm_protocol_socket_oldmsg_split(message->argument, 9)) == NULL) goto err; GString *gid = g_list_nth_data(arguments, 0); GString *id = g_list_nth_data(arguments, 1); GString *frac = g_list_nth_data(arguments, 2); GString *numproc = g_list_nth_data(arguments, 3); GString *nice = g_list_nth_data(arguments, 4); GString *flow_xml = g_list_nth_data(arguments, 5); GString *paths = g_list_nth_data(arguments, 6); /* Moab & MPI settings */ GString *account = g_list_nth_data(arguments, 7); GString *servers_mpi = g_list_nth_data(arguments, 8); g_debug("SERVERS MPI %s", servers_mpi->str); /* try to run and send return */ job_new(&job, client, gid, id, frac, numproc, nice, flow_xml, account, paths, servers_mpi); #ifdef DEBUG gchar *env_delay = getenv("GEBRD_RUN_DELAY_SEC"); if (env_delay != NULL) sleep(atoi(env_delay)); #endif if (gebrd_get_server_type() == GEBR_COMM_SERVER_TYPE_REGULAR) { /* send job message (job is created -promoted from waiting server response- at the client) */ g_debug("RUN_DEF: run task with rid %s", id->str); job_send_clients_job_notify(job); job_run_flow(job); } else { /* ask moab to run */ job_run_flow(job); /* send job message (job is created -promoted from waiting server response- at the client) * at moab we must run the process before sending the JOB message, because at * job_run_flow moab_jid is acquired. */ job_send_clients_job_notify(job); } /* frees */ gebr_comm_protocol_socket_oldmsg_split_free(arguments); } else if (message->hash == gebr_comm_protocol_defs.rnq_def.code_hash) { } else if (message->hash == gebr_comm_protocol_defs.flw_def.code_hash) { } else if (message->hash == gebr_comm_protocol_defs.clr_def.code_hash) { GList *arguments; GString *rid; GebrdJob *job; /* organize message data */ if ((arguments = gebr_comm_protocol_socket_oldmsg_split(message->argument, 1)) == NULL) goto err; rid = g_list_nth_data(arguments, 0); job = job_find(rid); if (job != NULL) job_clear(job); /* frees */ gebr_comm_protocol_socket_oldmsg_split_free(arguments); } else if (message->hash == gebr_comm_protocol_defs.end_def.code_hash) { GList *arguments; GString *rid; GebrdJob *job; /* organize message data */ if ((arguments = gebr_comm_protocol_socket_oldmsg_split(message->argument, 1)) == NULL) goto err; rid = g_list_nth_data(arguments, 0); /* try to run and send return */ job = job_find(rid); if (job != NULL) { job_end(job); } /* frees */ gebr_comm_protocol_socket_oldmsg_split_free(arguments); } else if (message->hash == gebr_comm_protocol_defs.kil_def.code_hash) { GList *arguments; GString *rid; GebrdJob *job; /* organize message data */ if ((arguments = gebr_comm_protocol_socket_oldmsg_split(message->argument, 1)) == NULL) goto err; rid = g_list_nth_data(arguments, 0); /* try to run and send return */ job = job_find(rid); if (job != NULL) { job_kill(job); } /* frees */ gebr_comm_protocol_socket_oldmsg_split_free(arguments); } else if (message->hash == gebr_comm_protocol_defs.path_def.code_hash) { GList *arguments; if ((arguments = gebr_comm_protocol_socket_oldmsg_split(message->argument, 3)) == NULL) goto err; GString *new_path = g_list_nth_data(arguments, 0); GString *old_path = g_list_nth_data(arguments, 1); GString *opt = g_list_nth_data(arguments, 2); g_debug("new_path:%s, old_path:%s, opt:%s", new_path->str, old_path->str, opt->str); GList *new_paths= parse_comma_separated_string(new_path->str); gint option = gebr_comm_protocol_path_str_to_enum(opt->str); gint status_id = -1; gboolean flag_exists = FALSE; gboolean flag_error = FALSE; switch (option) { case GEBR_COMM_PROTOCOL_PATH_CREATE: for (GList *j = new_paths; j; j = j->next) { GString *path = j->data; if (g_file_test(path->str, G_FILE_TEST_IS_DIR)){ flag_exists = TRUE; } else if (*(path->str) && g_mkdir_with_parents(path->str, 0700)) { flag_error = TRUE; break; } if (g_access(path->str, W_OK)==-1){ flag_error = TRUE; break; } } if (flag_error) status_id = GEBR_COMM_PROTOCOL_STATUS_PATH_ERROR; else if (flag_exists) status_id = GEBR_COMM_PROTOCOL_STATUS_PATH_EXISTS; else status_id = GEBR_COMM_PROTOCOL_STATUS_PATH_OK; break; case GEBR_COMM_PROTOCOL_PATH_RENAME: g_debug("Renaming %s to %s", old_path->str, new_path->str); gboolean dir_exist = g_file_test(new_path->str, G_FILE_TEST_IS_DIR); gboolean create_dir = g_rename(old_path->str, new_path->str) == 0; if (!dir_exist && create_dir) status_id = GEBR_COMM_PROTOCOL_STATUS_PATH_OK; else if (dir_exist && !create_dir) status_id = GEBR_COMM_PROTOCOL_STATUS_PATH_EXISTS; else if (!dir_exist && !create_dir) status_id = GEBR_COMM_PROTOCOL_STATUS_PATH_ERROR; else status_id = -1; break; case GEBR_COMM_PROTOCOL_PATH_DELETE: for (GList *j = new_paths; j; j = j->next) { GString *path = j->data; if (g_rmdir(path->str)) status_id = GEBR_COMM_PROTOCOL_STATUS_PATH_ERROR; else status_id = GEBR_COMM_PROTOCOL_STATUS_PATH_OK; } break; default: g_warn_if_reached(); break; } g_debug("on %s, new_path:'%s', old_path:'%s', status_id: '%d'", __func__, new_path->str, old_path->str, status_id); /* frees */ gebr_comm_protocol_socket_oldmsg_split_free(arguments); gebr_comm_protocol_socket_oldmsg_send(socket, FALSE, gebr_comm_protocol_defs.ret_def, 2, gebrd->hostname, g_strdup_printf("%d", status_id)); } else if (message->hash == gebr_comm_protocol_defs.harakiri_def.code_hash) { /* Maestro wants me killed */ g_debug("Harakiri"); gebrd_quit(); } else { /* unknown message! */ goto err; } gebr_comm_message_free(message); client->socket->protocol->messages = g_list_delete_link(client->socket->protocol->messages, link); } return; err: gebr_comm_message_free(message); client->socket->protocol->messages = g_list_delete_link(client->socket->protocol->messages, link); client_disconnected(socket, client); }
uint32_t job_inval(void (*callback)(uint8_t status,void *extra),void *extra) { jobpool* jp = globalpool; return job_new(jp,OP_INVAL,NULL,callback,extra); }
/** * gstreamill_job_start: * @job: (in): json type of job description. * * Returns: json type of job execution result. */ gchar * gstreamill_job_start (Gstreamill *gstreamill, gchar *job_desc) { gchar *p, *name; Job *job; if (!jobdesc_is_valid (job_desc)) { p = g_strdup_printf ("{\n \"result\": \"failure\",\n \"reason\": \"invalid job\"\n}"); return p; } if (jobdesc_is_live (job_desc)) { GST_ERROR ("live job arrived:\n%s", job_desc); } else { GST_ERROR ("transcode job arrived:\n%s", job_desc); } /* create job object */ name = jobdesc_get_name (job_desc); if (get_job (gstreamill, name) != NULL) { GST_ERROR ("start job failure, duplicated name %s.", name); p = g_strdup_printf ("{\n \"result\": \"failure\",\n \"reason\": \"duplicated name\"\n}"); g_free (name); return p; } job = job_new ("job", job_desc, "name", name, "exe_path", gstreamill->exe_path, NULL); g_free (name); /* job initialize */ job->log_dir = gstreamill->log_dir; g_mutex_init (&(job->access_mutex)); job->is_live = jobdesc_is_live (job_desc); job->eos = FALSE; job->current_access = 0; job->age = 0; job->last_start_time = NULL; if (job_initialize (job, gstreamill->daemon) != 0) { p = g_strdup_printf ("{\n \"result\": \"failure\",\n \"reason\": \"initialize job failure\"\n}"); g_object_unref (job); return p; } if (job->is_live && (job_output_initialize (job) != 0)) { p = g_strdup_printf ("{\n \"result\": \"failure\",\n \"reason\": \"initialize job output failure\"\n}"); g_object_unref (job); return p; } /* reset and start job */ job_reset (job); if (gstreamill->daemon) { guint64 stat; stat = create_job_process (job); if (stat == JOB_STATE_PLAYING) { GST_ERROR ("Start job %s success", job->name); g_mutex_lock (&(gstreamill->job_list_mutex)); gstreamill->job_list = g_slist_append (gstreamill->job_list, job); g_mutex_unlock (&(gstreamill->job_list_mutex)); p = g_strdup_printf ("{\n \"name\": \"%s\",\n\"result\": \"success\"\n}", job->name); } else { GST_ERROR ("Start job %s failure, return stat: %s", job->name, job_state_get_name (stat)); g_object_unref (job); p = g_strdup_printf ("{\n \"result\": \"failure\",\n \"reason\": \"create process failure\"\n}"); } } else { job_encoders_output_initialize (job); if (job_start (job) == 0) { g_mutex_lock (&(gstreamill->job_list_mutex)); gstreamill->job_list = g_slist_append (gstreamill->job_list, job); g_mutex_unlock (&(gstreamill->job_list_mutex)); p = g_strdup ("{\n \"result\": \"success\"\n}"); } else { p = g_strdup_printf ("{\n \"result\": \"failure\",\n \"reason\": \"unknown\"\n}"); } } return p; }
/** * gstreamill_job_start: * @job: (in): json type of job description. * * Returns: json type of job execution result. */ gchar * gstreamill_job_start (Gstreamill *gstreamill, gchar *job_desc) { gchar *p, *name; Job *job; if (!jobdesc_is_valid (job_desc)) { p = g_strdup ("Invalid job"); return p; } if (jobdesc_is_live (job_desc)) { GST_ERROR ("live job arrived"); } else { GST_ERROR ("transcode job arrived"); } /* create job object */ name = jobdesc_get_name (job_desc); if (get_job (gstreamill, name) != NULL) { GST_ERROR ("start live job failure, duplicated name %s.", name); p = g_strdup_printf ("start live job failure, duplicated name %s.", name); g_free (name); return p; } job = job_new ("job", job_desc, "name", name, NULL); g_free (name); /* job initialize */ job->log_dir = gstreamill->log_dir; g_mutex_init (&(job->access_mutex)); job->is_live = jobdesc_is_live (job_desc); job->eos = FALSE; job->current_access = 0; job->age = 0; job->last_start_time = NULL; if (job_initialize (job, gstreamill->daemon) != 0) { p = g_strdup ("initialize job failure"); g_object_unref (job); return p; } /* reset and start job */ job_reset (job); if (gstreamill->daemon) { p = create_job_process (job); GST_ERROR ("%s: %s", p, job->name); if (g_str_has_suffix (p, "success")) { g_mutex_lock (&(gstreamill->job_list_mutex)); gstreamill->job_list = g_slist_append (gstreamill->job_list, job); g_mutex_unlock (&(gstreamill->job_list_mutex)); } else { g_object_unref (job); } } else { if (job_start (job) == 0) { g_mutex_lock (&(gstreamill->job_list_mutex)); gstreamill->job_list = g_slist_append (gstreamill->job_list, job); g_mutex_unlock (&(gstreamill->job_list_mutex)); p = g_strdup ("success"); } else { p = g_strdup ("failure"); } } return p; }