Ejemplo n.º 1
0
static struct wproc_job *create_job(int type, void *arg, time_t timeout, const char *cmd)
{
	struct wproc_job *job;
	struct wproc_worker *wp;

	wp = get_worker(cmd);
	if (!wp)
		return NULL;

	job = calloc(1, sizeof(*job));
	if (!job) {
		logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Failed to allocate memory for worker job: %s\n", strerror(errno));
		return NULL;
	}

	job->wp = wp;
	job->id = get_job_id(wp);
	job->type = type;
	job->arg = arg;
	job->timeout = timeout;
	if (fanout_add(wp->jobs, job->id, job) < 0 || !(job->command = strdup(cmd))) {
		free(job);
		return NULL;
	}

	return job;
}
Ejemplo n.º 2
0
Archivo: workers.c Proyecto: atj/nagios
/*
 * Handles adding the command and macros to the kvvec,
 * as well as shipping the command off to a designated
 * worker
 */
static int wproc_run_job(worker_job *job, nagios_macros *mac)
{
	static struct kvvec kvv = KVVEC_INITIALIZER;
	worker_process *wp;

	/*
	 * get_worker() also adds job to the workers list
	 * and sets job_id
	 */
	wp = get_worker(job);
	if (!wp || job->id < 0)
		return ERROR;

	/*
	 * XXX FIXME: add environment macros as
	 *  kvvec_addkv(kvv, "env", "NAGIOS_LALAMACRO=VALUE");
	 *  kvvec_addkv(kvv, "env", "NAGIOS_LALAMACRO2=VALUE");
	 * so workers know to add them to environment. For now,
	 * we don't support that though.
	 */
	if (!kvvec_init(&kvv, 4))	/* job_id, type, command and timeout */
		return ERROR;

	kvvec_addkv(&kvv, "job_id", (char *)mkstr("%d", job->id));
	kvvec_addkv(&kvv, "type", (char *)mkstr("%d", job->type));
	kvvec_addkv(&kvv, "command", job->command);
	kvvec_addkv(&kvv, "timeout", (char *)mkstr("%u", job->timeout));
	send_kvvec(wp->sd, &kvv);
	wp->jobs_running++;
	wp->jobs_started++;

	return 0;
}
Ejemplo n.º 3
0
void G_begin_execute(void (*func)(void *), void *closure, void **ref, int force)
{
    struct worker *w;
 
    if (*ref)
	G_fatal_error(_("Task already has a worker"));

    pthread_mutex_lock(&worker_mutex);

    while (w = get_worker(), force && !w)
	pthread_cond_wait(&worker_cond, &worker_mutex);
    *ref = w;

    if (!w) {
	pthread_mutex_unlock(&worker_mutex);
	(*func)(closure);
	return;
    }

    pthread_mutex_lock(&w->mutex);
    w->func = func;
    w->closure = closure;
    w->ref = ref;
    pthread_cond_signal(&w->cond);
    pthread_mutex_unlock(&w->mutex);

    pthread_mutex_unlock(&worker_mutex);
}
Ejemplo n.º 4
0
static void fo_reassign_wproc_job(void *job_)
{
	struct wproc_job *job = (struct wproc_job *)job_;
	job->wp = get_worker(job->command);
	job->id = get_job_id(job->wp);
	/* macros aren't used right now anyways */
	wproc_run_job(job, NULL);
}
Ejemplo n.º 5
0
/*
 * common routine for extract_path functions
 */
static inline Datum
get_path_all(PG_FUNCTION_ARGS, bool as_text)
{
	text	   *json = PG_GETARG_TEXT_P(0);
	ArrayType  *path = PG_GETARG_ARRAYTYPE_P(1);
	text	   *result;
	Datum	   *pathtext;
	bool	   *pathnulls;
	int			npath;
	char	  **tpath;
	int		   *ipath;
	int			i;
	long		ind;
	char	   *endptr;

	if (array_contains_nulls(path))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("cannot call function with null path elements")));


	deconstruct_array(path, TEXTOID, -1, false, 'i',
					  &pathtext, &pathnulls, &npath);

	tpath = palloc(npath * sizeof(char *));
	ipath = palloc(npath * sizeof(int));


	for (i = 0; i < npath; i++)
	{
		tpath[i] = TextDatumGetCString(pathtext[i]);
		if (*tpath[i] == '\0')
			ereport(
					ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				   errmsg("cannot call function with empty path elements")));

		/*
		 * we have no idea at this stage what structure the document is so
		 * just convert anything in the path that we can to an integer and set
		 * all the other integers to -1 which will never match.
		 */
		ind = strtol(tpath[i], &endptr, 10);
		if (*endptr == '\0' && ind <= INT_MAX && ind >= 0)
			ipath[i] = (int) ind;
		else
			ipath[i] = -1;
	}


	result = get_worker(json, NULL, -1, tpath, ipath, npath, as_text);

	if (result != NULL)
		PG_RETURN_TEXT_P(result);
	else
		PG_RETURN_NULL();
}
Ejemplo n.º 6
0
Datum
json_array_element_text(PG_FUNCTION_ARGS)
{
	text	   *json = PG_GETARG_TEXT_P(0);
	text	   *result;
	int			element = PG_GETARG_INT32(1);

	result = get_worker(json, NULL, element, NULL, NULL, -1, true);

	if (result != NULL)
		PG_RETURN_TEXT_P(result);
	else
		PG_RETURN_NULL();
}
Ejemplo n.º 7
0
Datum
json_object_field_text(PG_FUNCTION_ARGS)
{
	text	   *json = PG_GETARG_TEXT_P(0);
	text	   *result;
	text	   *fname = PG_GETARG_TEXT_P(1);
	char	   *fnamestr = text_to_cstring(fname);

	result = get_worker(json, fnamestr, -1, NULL, NULL, -1, true);

	if (result != NULL)
		PG_RETURN_TEXT_P(result);
	else
		PG_RETURN_NULL();
}
Ejemplo n.º 8
0
void ThreadPool::operator()()
{
	try
	{
		while (!boost::this_thread::interruption_requested())
		{
			taskp task;
			if (!m_tasks.timed_pop_front(task, m_idle)) {
				reclaim_workers();
			} else {
				workerp worker;
				get_worker(worker);
				worker->acquire(task);
			}
		}
	} catch (boost::thread_interrupted &msg) {
	}
}
Ejemplo n.º 9
0
	bool resend_pending(void) {
		if(!pending.ready) return false;
		for(;;) {
			size_t worker = get_worker();
			if(worker == -1) {
				// clog us up until we can get a worker
				printf("can't find a worker to send %d\n", pending.m.id);
				return false;
			}
			if(send_message(worker,pending.m)) {
				puts("sent message");
				pfd[INCOMING].events = POLLIN;
				pending.ready = false;
				return true;
			}
			perror("send message failed...");
			workers[worker].status = BUSY;
			// then try getting another worker.
		}
	}
Ejemplo n.º 10
0
    void on_subscribe(Subscriber o) const {
        static_assert(is_subscriber<Subscriber>::value, "subscribe must be passed a subscriber");

        // creates a worker whose lifetime is the same as this subscription
        auto coordinator = initial.coordination.create_coordinator(o.get_subscription());

        auto controller = coordinator.get_worker();

        auto counter = std::make_shared<long>(0);

        auto producer = [o, counter](const rxsc::schedulable&) {
            // send next value
            o.on_next(++(*counter));
        };

        auto selectedProducer = on_exception(
            [&](){return coordinator.act(producer);},
            o);
        if (selectedProducer.empty()) {
            return;
        }

        controller.schedule_periodically(initial.initial, initial.period, selectedProducer.get());
    }
Ejemplo n.º 11
0
size_t get_worker(void) {
	// get a worker
	// off, so we don't check worker 0 a million times
	static size_t off = -1;
	static int tries = 0;
	++off;
	int which;
	for(which=0;which<numworkers;++which) {
		size_t derp = (which+off)%numworkers;
		switch(workers[derp].status) {
		case IDLE:
			workers[derp].status = BUSY;
			PFD(derp).events = POLLIN;
			tries = 0;
			return derp;
		};
	}

	if(tries < 3) {
		++tries;
		// if we timeout 3 times, stop waiting for idle workers.
		return -1;
	}

	/* no idle found, try starting some workers */
	if(numworkers < MAXWORKERS) {
		// add a worker to the end
		if(start_worker()) {
			tries = 0;
			return numworkers-1;
		}
	} else {
		reap_workers();
		for(which=0;which<numworkers;++which) {
			if(workers[which].status == DOOMED) {
				/*
					if 995 ns left (expiration - now) and doom delay is 1000ns
					1000 - 995 < 50, so wait a teensy bit longer please
				*/
				Time diff = timediff(DOOM_DELAY,
														 timediff(workers[which].expiration,
																			getnow()));
				if(diff.tv_nsec > 50) {
					// waited too long, kill the thing.
					kill_worker(which);
					if(start_worker()) {
						tries = 0;
						return numworkers-1;
					}
				}
			}
		}
	}
	if(wait_for_accept()) {
		if(accept_workers()) {
			return get_worker();
		}
	}
	// have to wait until the new worker connects
	errno = EAGAIN; // eh
	return -1;
}