/* * Copyright (C) 2016, 2017, 2018 "IoT.bzh" * Author José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include "jobs.h" #include "sig-monitor.h" #include "verbose.h" #include "jobs.h" struct jobloop; struct job { struct job *next; const void *group; int timeout; void (*callback)(int signum, void* arg); void *closure; }; static struct job *first, *last; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static int add_job(const void *group, int timeout, void (*callback)(int signum, void *closure), void *closure) { struct job *j; j = malloc(sizeof*j); if (!j) { errno = ENOMEM; return -1; } j->next = 0; j->group = group; j->timeout = timeout; j->callback = callback; j->closure = closure; pthread_mutex_lock(&mutex); if (first) last->next = j; else first = j; last = j; pthread_mutex_unlock(&mutex); return 0; } static void *thrrun(void *arg) { struct job *j; pthread_mutex_lock(&mutex); j = first; if (j) first = j->next; pthread_mutex_unlock(&mutex); if (j) { j->callback(0, j->closure); free(j); } return 0; } int jobs_queue( const void *group, int timeout, void (*callback)(int signum, void* arg), void *arg) { pthread_t tid; int rc = add_job(group, timeout, callback, arg); if (!rc) { rc = pthread_create(&tid, NULL, thrrun, NULL); if (rc) rc = -1; } return rc; } #if 0 int jobs_enter( const void *group, int timeout, void (*callback)(int signum, void *closure, struct jobloop *jobloop), void *closure) { return 0; } int jobs_leave(struct jobloop *jobloop) { return 0; } int jobs_call( const void *group, int timeout, void (*callback)(int, void*), void *arg) { return 0; } struct sd_event *jobs_get_sd_event() { struct sd_event *r; int rc = sd_event_default(&r); return rc < 0 ? NULL : r; } void jobs_terminate() { } int jobs_start(int allowed_count, int start_count, int waiter_count, void (*start)(int signum)) { start(0); return 0; } #endif