mirror of
https://github.com/lxsang/ant-http
synced 2024-12-26 00:38:21 +01:00
feat(v2.0.0): Improvement + add IPv6 support
All checks were successful
gitea-sync/ant-http/pipeline/head This commit looks good
All checks were successful
gitea-sync/ant-http/pipeline/head This commit looks good
- fix: scheduler causes segmentfault when exiting the server - Add support for IPv6 protocol
This commit is contained in:
parent
32552ee0ed
commit
9c25e62c0a
@ -1,5 +1,5 @@
|
|||||||
# initialise autoconf and set up some basic information about the program we’re packaging
|
# initialise autoconf and set up some basic information about the program we’re packaging
|
||||||
AC_INIT([antd], [1.0.6b], [xsang.le@gmail.com])
|
AC_INIT([antd], [2.0.0], [xsang.le@gmail.com])
|
||||||
|
|
||||||
# We’re going to use automake for this project
|
# We’re going to use automake for this project
|
||||||
AM_INIT_AUTOMAKE([subdir-objects])
|
AM_INIT_AUTOMAKE([subdir-objects])
|
||||||
|
@ -31,6 +31,13 @@
|
|||||||
|
|
||||||
#define HEADER_MAX_SIZE 8192
|
#define HEADER_MAX_SIZE 8192
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct sockaddr_in6 addr6;
|
||||||
|
struct sockaddr_in addr4;
|
||||||
|
} antd_server_sockaddr_t;
|
||||||
|
|
||||||
|
|
||||||
// define all basic mime here
|
// define all basic mime here
|
||||||
static mime_t _mimes[] = {
|
static mime_t _mimes[] = {
|
||||||
{"image/bmp", "bmp"},
|
{"image/bmp", "bmp"},
|
||||||
@ -52,6 +59,7 @@ static mime_t _mimes[] = {
|
|||||||
|
|
||||||
static pthread_mutex_t server_mux = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t server_mux = PTHREAD_MUTEX_INITIALIZER;
|
||||||
config_t server_config;
|
config_t server_config;
|
||||||
|
|
||||||
config_t *config()
|
config_t *config()
|
||||||
{
|
{
|
||||||
return &server_config;
|
return &server_config;
|
||||||
@ -259,6 +267,7 @@ static int config_handler(void *conf, const char *section, const char *name,
|
|||||||
p->htdocs = NULL;
|
p->htdocs = NULL;
|
||||||
p->plugins = NULL;
|
p->plugins = NULL;
|
||||||
p->sock = -1;
|
p->sock = -1;
|
||||||
|
p->type = ANTD_PROTO_ALL;
|
||||||
p->rules = dict_n(1);
|
p->rules = dict_n(1);
|
||||||
dput(pconfig->ports, buf, p);
|
dput(pconfig->ports, buf, p);
|
||||||
p->port = atoi(buf);
|
p->port = atoi(buf);
|
||||||
@ -290,6 +299,21 @@ static int config_handler(void *conf, const char *section, const char *name,
|
|||||||
if (p->usessl)
|
if (p->usessl)
|
||||||
pconfig->enable_ssl = 1;
|
pconfig->enable_ssl = 1;
|
||||||
}
|
}
|
||||||
|
else if(strcmp(name, "protocol") == 0)
|
||||||
|
{
|
||||||
|
if(strcmp(value, "ipv4") == 0)
|
||||||
|
{
|
||||||
|
p->type = ANTD_PROTO_IP_4;
|
||||||
|
}
|
||||||
|
else if(strcmp(value, "ipv6") == 0)
|
||||||
|
{
|
||||||
|
p->type = ANTD_PROTO_IP_6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERROR("Unknown IP protocol setting %s. Enable both.", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// other thing should be rules
|
// other thing should be rules
|
||||||
@ -366,7 +390,7 @@ void load_config(const char *file)
|
|||||||
server_config.db_path = strdup("databases/");
|
server_config.db_path = strdup("databases/");
|
||||||
// server_config.htdocs = "htdocs/";
|
// server_config.htdocs = "htdocs/";
|
||||||
server_config.tmpdir = strdup("/tmp/");
|
server_config.tmpdir = strdup("/tmp/");
|
||||||
server_config.stat_fifo_path = strdup("/var/run/antd_stat");
|
server_config.stat_fifo_path = strdup("");
|
||||||
server_config.n_workers = 4;
|
server_config.n_workers = 4;
|
||||||
server_config.backlog = 1000;
|
server_config.backlog = 1000;
|
||||||
server_config.handlers = dict();
|
server_config.handlers = dict();
|
||||||
@ -792,11 +816,30 @@ void *serve_file(void *data)
|
|||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
int startup(unsigned *port)
|
int startup(unsigned *port, int ipv6)
|
||||||
{
|
{
|
||||||
int httpd = 0;
|
int httpd = 0;
|
||||||
struct sockaddr_in name;
|
antd_server_sockaddr_t name;
|
||||||
httpd = socket(PF_INET, SOCK_STREAM, 0);
|
memset(&name, 0, sizeof(name));
|
||||||
|
struct sockaddr *ptr;
|
||||||
|
// TODO: allow to set listen address
|
||||||
|
if(ipv6)
|
||||||
|
{
|
||||||
|
name.addr6.sin6_port = htons(*port);
|
||||||
|
name.addr6.sin6_family = AF_INET6;
|
||||||
|
name.addr6.sin6_addr = in6addr_any;
|
||||||
|
httpd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||||
|
ptr = (struct sockaddr *) & name.addr6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name.addr4.sin_port = htons(*port);
|
||||||
|
name.addr4.sin_family = AF_INET;
|
||||||
|
name.addr4.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
httpd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
ptr = (struct sockaddr *) & name.addr4;
|
||||||
|
}
|
||||||
|
|
||||||
if (httpd == -1)
|
if (httpd == -1)
|
||||||
{
|
{
|
||||||
ERROR("Port %d - socket: %s", *port, strerror(errno));
|
ERROR("Port %d - socket: %s", *port, strerror(errno));
|
||||||
@ -808,11 +851,7 @@ int startup(unsigned *port)
|
|||||||
ERROR("Unable to set reuse address on port %d - setsockopt: %s", *port, strerror(errno));
|
ERROR("Unable to set reuse address on port %d - setsockopt: %s", *port, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&name, 0, sizeof(name));
|
if (bind(httpd, ptr, sizeof(name)) < 0)
|
||||||
name.sin_family = AF_INET;
|
|
||||||
name.sin_port = htons(*port);
|
|
||||||
name.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
if (bind(httpd, (struct sockaddr *)&name, sizeof(name)) < 0)
|
|
||||||
{
|
{
|
||||||
ERROR("Port %d -bind: %s", *port, strerror(errno));
|
ERROR("Port %d -bind: %s", *port, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
@ -825,15 +864,22 @@ int startup(unsigned *port)
|
|||||||
ERROR("Port %d - getsockname: %s", *port, strerror(errno));
|
ERROR("Port %d - getsockname: %s", *port, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*port = ntohs(name.sin_port);
|
if(ipv6)
|
||||||
|
{
|
||||||
|
*port = ntohs(name.addr6.sin6_port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*port = ntohs(name.addr4.sin_port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG("back log is %d", server_config.backlog);
|
|
||||||
if (listen(httpd, server_config.backlog) < 0)
|
if (listen(httpd, server_config.backlog) < 0)
|
||||||
{
|
{
|
||||||
ERROR("Port %d - listen: %s", *port, strerror(errno));
|
ERROR("Port %d - listen: %s", *port, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
LOG("%s Listen on port %d", ipv6?"IPv6":"IPv4", *port );
|
||||||
return (httpd);
|
return (httpd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ void cat(void *, FILE *);
|
|||||||
void cannot_execute(void *);
|
void cannot_execute(void *);
|
||||||
//int get_line(int, char *, int);
|
//int get_line(int, char *, int);
|
||||||
void *serve_file(void *);
|
void *serve_file(void *);
|
||||||
int startup(unsigned *);
|
int startup(unsigned *, int);
|
||||||
int rule_check(const char *, const char *, const char *, const char *, const char *, char *);
|
int rule_check(const char *, const char *, const char *, const char *, const char *, char *);
|
||||||
void ws_confirm_request(void *, const char *);
|
void ws_confirm_request(void *, const char *);
|
||||||
char *post_url_decode(void *client, int len);
|
char *post_url_decode(void *client, int len);
|
||||||
|
23
httpd.c
23
httpd.c
@ -165,7 +165,7 @@ static void stop_serve(int dummy)
|
|||||||
sigprocmask(SIG_UNBLOCK, &mask, NULL);
|
sigprocmask(SIG_UNBLOCK, &mask, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void antd_monitor(port_config_t *pcnf)
|
static void antd_monitor(port_config_t *pcnf, int sock)
|
||||||
{
|
{
|
||||||
antd_task_t *task = NULL;
|
antd_task_t *task = NULL;
|
||||||
int client_sock = -1;
|
int client_sock = -1;
|
||||||
@ -173,9 +173,9 @@ static void antd_monitor(port_config_t *pcnf)
|
|||||||
socklen_t client_name_len = sizeof(client_name);
|
socklen_t client_name_len = sizeof(client_name);
|
||||||
char *client_ip = NULL;
|
char *client_ip = NULL;
|
||||||
config_t *conf = config();
|
config_t *conf = config();
|
||||||
if (pcnf->sock > 0)
|
if (sock > 0)
|
||||||
{
|
{
|
||||||
client_sock = accept(pcnf->sock, (struct sockaddr *)&client_name, &client_name_len);
|
client_sock = accept(sock, (struct sockaddr *)&client_name, &client_name_len);
|
||||||
if (client_sock > 0)
|
if (client_sock > 0)
|
||||||
{
|
{
|
||||||
// just dump the scheduler when we have a connection
|
// just dump the scheduler when we have a connection
|
||||||
@ -332,6 +332,9 @@ int main(int argc, char *argv[])
|
|||||||
int status, maxfd = 0;
|
int status, maxfd = 0;
|
||||||
int nlisten = 0;
|
int nlisten = 0;
|
||||||
// load the config first
|
// load the config first
|
||||||
|
#ifdef VERSION
|
||||||
|
LOG("Antd server version: " VERSION);
|
||||||
|
#endif
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
load_config(CONFIG_FILE);
|
load_config(CONFIG_FILE);
|
||||||
else
|
else
|
||||||
@ -379,12 +382,18 @@ int main(int argc, char *argv[])
|
|||||||
pcnf = (port_config_t *)it->value;
|
pcnf = (port_config_t *)it->value;
|
||||||
if (pcnf)
|
if (pcnf)
|
||||||
{
|
{
|
||||||
pcnf->sock = startup(&pcnf->port);
|
if(pcnf->type == ANTD_PROTO_IP_4)
|
||||||
|
{
|
||||||
|
pcnf->sock = startup(&pcnf->port,0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pcnf->sock = startup(&pcnf->port,1);
|
||||||
|
}
|
||||||
if (pcnf->sock > 0)
|
if (pcnf->sock > 0)
|
||||||
{
|
{
|
||||||
set_nonblock(pcnf->sock);
|
set_nonblock(pcnf->sock);
|
||||||
FD_SET(pcnf->sock, &master_set);
|
FD_SET(pcnf->sock, &master_set);
|
||||||
LOG("Listening on port %d", pcnf->port);
|
|
||||||
maxfd = pcnf->sock > maxfd ? pcnf->sock : maxfd;
|
maxfd = pcnf->sock > maxfd ? pcnf->sock : maxfd;
|
||||||
nlisten++;
|
nlisten++;
|
||||||
}
|
}
|
||||||
@ -396,7 +405,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (nlisten == 0)
|
if (nlisten == 0)
|
||||||
{
|
{
|
||||||
ERROR("No port is listenned, quit!!");
|
ERROR("No port is listened, quit!!");
|
||||||
stop_serve(0);
|
stop_serve(0);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -441,7 +450,7 @@ int main(int argc, char *argv[])
|
|||||||
pcnf = (port_config_t *)it->value;
|
pcnf = (port_config_t *)it->value;
|
||||||
if (pcnf && pcnf->sock > 0 && FD_ISSET(pcnf->sock, &working_set))
|
if (pcnf && pcnf->sock > 0 && FD_ISSET(pcnf->sock, &working_set))
|
||||||
{
|
{
|
||||||
antd_monitor(pcnf);
|
antd_monitor(pcnf, pcnf->sock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,12 @@ typedef enum
|
|||||||
ANTD_CNONE
|
ANTD_CNONE
|
||||||
} antd_compress_t;
|
} antd_compress_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ANTD_PROTO_IP_4,
|
||||||
|
ANTD_PROTO_IP_6,
|
||||||
|
ANTD_PROTO_ALL
|
||||||
|
} antd_proto_t;
|
||||||
|
|
||||||
//extern config_t server_config;
|
//extern config_t server_config;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -49,6 +55,7 @@ typedef struct
|
|||||||
char *htdocs;
|
char *htdocs;
|
||||||
char* plugins;
|
char* plugins;
|
||||||
int sock;
|
int sock;
|
||||||
|
antd_proto_t type;
|
||||||
dictionary_t rules;
|
dictionary_t rules;
|
||||||
} port_config_t;
|
} port_config_t;
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include "bst.h"
|
#include "bst.h"
|
||||||
|
|
||||||
#define MAX_VALIDITY_INTERVAL 30
|
#define MAX_VALIDITY_INTERVAL 30
|
||||||
#define MAX_FIFO_NAME_SZ 255
|
#define MAX_NAME_SZ 255
|
||||||
|
|
||||||
// callback definition
|
// callback definition
|
||||||
struct _antd_callback_t
|
struct _antd_callback_t
|
||||||
@ -70,7 +70,9 @@ struct _antd_scheduler_t
|
|||||||
int n_workers;
|
int n_workers;
|
||||||
int pending_task;
|
int pending_task;
|
||||||
int id_allocator;
|
int id_allocator;
|
||||||
char stat_fifo[MAX_FIFO_NAME_SZ];
|
char stat_fifo[MAX_NAME_SZ];
|
||||||
|
char sched_name[MAX_NAME_SZ];
|
||||||
|
char worker_hub[MAX_NAME_SZ];
|
||||||
int stat_fd;
|
int stat_fd;
|
||||||
pthread_t stat_tid;
|
pthread_t stat_tid;
|
||||||
};
|
};
|
||||||
@ -122,13 +124,14 @@ static void stop(antd_scheduler_t *scheduler)
|
|||||||
pthread_join(scheduler->workers[i].tid, NULL);
|
pthread_join(scheduler->workers[i].tid, NULL);
|
||||||
if (scheduler->workers)
|
if (scheduler->workers)
|
||||||
free(scheduler->workers);
|
free(scheduler->workers);
|
||||||
|
if(scheduler->stat_tid)
|
||||||
(void)pthread_cancel(scheduler->stat_tid);
|
(void)pthread_cancel(scheduler->stat_tid);
|
||||||
// destroy all the mutex
|
// destroy all the mutex
|
||||||
pthread_mutex_destroy(&scheduler->scheduler_lock);
|
pthread_mutex_destroy(&scheduler->scheduler_lock);
|
||||||
pthread_mutex_destroy(&scheduler->worker_lock);
|
pthread_mutex_destroy(&scheduler->worker_lock);
|
||||||
pthread_mutex_destroy(&scheduler->pending_lock);
|
pthread_mutex_destroy(&scheduler->pending_lock);
|
||||||
sem_unlink("scheduler");
|
sem_unlink(scheduler->sched_name);
|
||||||
sem_unlink("worker");
|
sem_unlink(scheduler->worker_hub);
|
||||||
sem_close(scheduler->scheduler_sem);
|
sem_close(scheduler->scheduler_sem);
|
||||||
sem_close(scheduler->worker_sem);
|
sem_close(scheduler->worker_sem);
|
||||||
}
|
}
|
||||||
@ -257,25 +260,25 @@ static void antd_task_dump(int fd, antd_task_t* task, char* buffer)
|
|||||||
}
|
}
|
||||||
int ret;
|
int ret;
|
||||||
// send statistic on task data
|
// send statistic on task data
|
||||||
snprintf(buffer, MAX_FIFO_NAME_SZ, "---- Task %d created at: %lu ----\n", task->id, task->stamp);
|
snprintf(buffer, MAX_NAME_SZ, "---- Task %d created at: %lu ----\n", task->id, task->stamp);
|
||||||
ret = write(fd, buffer, strlen(buffer));
|
ret = write(fd, buffer, strlen(buffer));
|
||||||
|
|
||||||
// send statistic on task data
|
// send statistic on task data
|
||||||
snprintf(buffer, MAX_FIFO_NAME_SZ, "Access time: %lu\nn", (unsigned long)task->access_time);
|
snprintf(buffer, MAX_NAME_SZ, "Access time: %lu\nn", (unsigned long)task->access_time);
|
||||||
ret = write(fd, buffer, strlen(buffer));
|
ret = write(fd, buffer, strlen(buffer));
|
||||||
|
|
||||||
snprintf(buffer, MAX_FIFO_NAME_SZ, "Current time: %lu\n", (unsigned long)time(NULL));
|
snprintf(buffer, MAX_NAME_SZ, "Current time: %lu\n", (unsigned long)time(NULL));
|
||||||
ret = write(fd, buffer, strlen(buffer));
|
ret = write(fd, buffer, strlen(buffer));
|
||||||
|
|
||||||
if (task->handle)
|
if (task->handle)
|
||||||
{
|
{
|
||||||
snprintf(buffer, MAX_FIFO_NAME_SZ, "Has handle: yes\n");
|
snprintf(buffer, MAX_NAME_SZ, "Has handle: yes\n");
|
||||||
ret = write(fd, buffer, strlen(buffer));
|
ret = write(fd, buffer, strlen(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task->callback)
|
if (task->callback)
|
||||||
{
|
{
|
||||||
snprintf(buffer, MAX_FIFO_NAME_SZ, "Has callback: yes\n");
|
snprintf(buffer, MAX_NAME_SZ, "Has callback: yes\n");
|
||||||
ret = write(fd, buffer, strlen(buffer));
|
ret = write(fd, buffer, strlen(buffer));
|
||||||
}
|
}
|
||||||
UNUSED(ret);
|
UNUSED(ret);
|
||||||
@ -297,7 +300,7 @@ static void *statistic(antd_scheduler_t *scheduler)
|
|||||||
{
|
{
|
||||||
struct pollfd pfd;
|
struct pollfd pfd;
|
||||||
int ret;
|
int ret;
|
||||||
char buffer[MAX_FIFO_NAME_SZ];
|
char buffer[MAX_NAME_SZ];
|
||||||
void *argc[2];
|
void *argc[2];
|
||||||
while (scheduler->status)
|
while (scheduler->status)
|
||||||
{
|
{
|
||||||
@ -336,7 +339,7 @@ static void *statistic(antd_scheduler_t *scheduler)
|
|||||||
{
|
{
|
||||||
pthread_mutex_lock(&scheduler->scheduler_lock);
|
pthread_mutex_lock(&scheduler->scheduler_lock);
|
||||||
// write statistic data
|
// write statistic data
|
||||||
snprintf(buffer, MAX_FIFO_NAME_SZ, "Pending task: %d. Detail:\n", scheduler->pending_task);
|
snprintf(buffer, MAX_NAME_SZ, "Pending task: %d. Detail:\n", scheduler->pending_task);
|
||||||
ret = write(scheduler->stat_fd, buffer, strlen(buffer));
|
ret = write(scheduler->stat_fd, buffer, strlen(buffer));
|
||||||
|
|
||||||
bst_for_each(scheduler->task_queue, print_static_info, argc, 2);
|
bst_for_each(scheduler->task_queue, print_static_info, argc, 2);
|
||||||
@ -346,7 +349,7 @@ static void *statistic(antd_scheduler_t *scheduler)
|
|||||||
// write worker current task
|
// write worker current task
|
||||||
for (int i = 0; i < scheduler->n_workers; i++)
|
for (int i = 0; i < scheduler->n_workers; i++)
|
||||||
{
|
{
|
||||||
snprintf(buffer, MAX_FIFO_NAME_SZ, "Worker: %d. Detail:\n", i);
|
snprintf(buffer, MAX_NAME_SZ, "Worker: %d. Detail:\n", i);
|
||||||
ret = write(scheduler->stat_fd, buffer, strlen(buffer));
|
ret = write(scheduler->stat_fd, buffer, strlen(buffer));
|
||||||
if(scheduler->workers[i].current_task)
|
if(scheduler->workers[i].current_task)
|
||||||
{
|
{
|
||||||
@ -407,20 +410,25 @@ antd_scheduler_t *antd_scheduler_init(int n, const char *stat_name)
|
|||||||
scheduler->pending_task = 0;
|
scheduler->pending_task = 0;
|
||||||
scheduler->stat_fd = -1;
|
scheduler->stat_fd = -1;
|
||||||
scheduler->id_allocator = 0;
|
scheduler->id_allocator = 0;
|
||||||
(void)memset(scheduler->stat_fifo, 0, MAX_FIFO_NAME_SZ);
|
scheduler->stat_tid = 0;
|
||||||
|
int pid = getpid();
|
||||||
|
snprintf(scheduler->sched_name,MAX_NAME_SZ, "scheduler.%d",pid);
|
||||||
|
snprintf(scheduler->worker_hub,MAX_NAME_SZ, "worker.%d",pid);
|
||||||
|
(void)memset(scheduler->stat_fifo, 0, MAX_NAME_SZ);
|
||||||
if (stat_name)
|
if (stat_name)
|
||||||
{
|
{
|
||||||
(void)strncpy(scheduler->stat_fifo, stat_name, MAX_FIFO_NAME_SZ - 1);
|
(void)strncpy(scheduler->stat_fifo, stat_name, MAX_NAME_SZ - 1);
|
||||||
}
|
}
|
||||||
// init semaphore
|
// init semaphore
|
||||||
scheduler->scheduler_sem = sem_open("scheduler", O_CREAT, 0600, 0);
|
|
||||||
|
scheduler->scheduler_sem = sem_open(scheduler->sched_name, O_CREAT, 0644, 0);
|
||||||
if (scheduler->scheduler_sem == SEM_FAILED)
|
if (scheduler->scheduler_sem == SEM_FAILED)
|
||||||
{
|
{
|
||||||
ERROR("Cannot open semaphore for scheduler");
|
ERROR("Cannot open semaphore for scheduler: %s", strerror(errno));
|
||||||
free(scheduler);
|
free(scheduler);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
scheduler->worker_sem = sem_open("worker", O_CREAT, 0600, 0);
|
scheduler->worker_sem = sem_open(scheduler->worker_hub, O_CREAT, 0600, 0);
|
||||||
if (!scheduler->worker_sem)
|
if (!scheduler->worker_sem)
|
||||||
{
|
{
|
||||||
ERROR("Cannot open semaphore for workers");
|
ERROR("Cannot open semaphore for workers");
|
||||||
@ -467,13 +475,14 @@ antd_scheduler_t *antd_scheduler_init(int n, const char *stat_name)
|
|||||||
// create the fifo file
|
// create the fifo file
|
||||||
if (mkfifo(scheduler->stat_fifo, 0666) == -1)
|
if (mkfifo(scheduler->stat_fifo, 0666) == -1)
|
||||||
{
|
{
|
||||||
ERROR("Unable to create statictis FIFO %s: %s", scheduler->stat_fifo, strerror(errno));
|
ERROR("Unable to create statistic FIFO %s: %s", scheduler->stat_fifo, strerror(errno));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (pthread_create(&scheduler->stat_tid, NULL, (void *(*)(void *))statistic, scheduler) != 0)
|
if (pthread_create(&scheduler->stat_tid, NULL, (void *(*)(void *))statistic, scheduler) != 0)
|
||||||
{
|
{
|
||||||
ERROR("pthread_create: cannot create statistic thread: %s", strerror(errno));
|
ERROR("pthread_create: cannot create statistic thread: %s", strerror(errno));
|
||||||
|
scheduler->stat_tid = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user