Skip to content
This repository was archived by the owner on Jul 14, 2019. It is now read-only.

Commit 3b14579

Browse files
lioramrNir Yeffet
authored andcommitted
timer_worker, timer with private stack/context
1 parent 662660e commit 3b14579

File tree

4 files changed

+117
-1
lines changed

4 files changed

+117
-1
lines changed

include/ribs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "sleep.h"
4949
#include "malloc.h"
5050
#include "timer.h"
51+
#include "timer_worker.h"
5152
#include "base64.h"
5253

5354
#endif // _RIBS__H_

include/timer_worker.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
This file is part of RIBS2.0 (Robust Infrastructure for Backend Systems).
3+
RIBS is an infrastructure for building great SaaS applications (but not
4+
limited to).
5+
6+
Copyright (C) Adap.tv, Inc.
7+
8+
RIBS is free software: you can redistribute it and/or modify
9+
it under the terms of the GNU Lesser General Public License as published by
10+
the Free Software Foundation, version 2.1 of the License.
11+
12+
RIBS is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
GNU Lesser General Public License for more details.
16+
17+
You should have received a copy of the GNU Lesser General Public License
18+
along with RIBS. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
#ifndef _TIMER_WORKER__H_
21+
#define _TIMER_WORKER__H_
22+
23+
#include "ribs_defs.h"
24+
25+
void *timer_worker_init(size_t stack_size, size_t reserved_size, time_t usec_initial, void (*user_func)(void));
26+
int timer_worker_schedule_next(time_t usec);
27+
void *timer_worker_get_user_data(void);
28+
29+
#endif // _TIMER_WORKER__H_

src/ribs2_common.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
SRC=context.c epoll_worker.c ctx_pool.c http_server.c hashtable.c mime_types.c http_client_pool.c timeout_handler.c ribify.c logger.c daemonize.c http_headers.c http_cookies.c file_mapper.c ds_var_field.c file_utils.c lhashtable.c search.c json.c memalloc.c mempool.c sleep.c timer.c ringbuf.c ringfile.c sendemail.c ds_loader.c heap.c vmallocator.c base64.c http_file_server.c http_vhost.c thashtable.c json_dom.c vmbuf.c
1+
SRC=context.c epoll_worker.c ctx_pool.c http_server.c hashtable.c mime_types.c http_client_pool.c timeout_handler.c ribify.c logger.c daemonize.c http_headers.c http_cookies.c file_mapper.c ds_var_field.c file_utils.c lhashtable.c search.c json.c memalloc.c mempool.c sleep.c timer.c timer_worker.c ringbuf.c ringfile.c sendemail.c ds_loader.c heap.c vmallocator.c base64.c http_file_server.c http_vhost.c thashtable.c json_dom.c vmbuf.c
22
ASM=context_asm.S
33
CFLAGS+= -I ../include

src/timer_worker.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
This file is part of RIBS2.0 (Robust Infrastructure for Backend Systems).
3+
RIBS is an infrastructure for building great SaaS applications (but not
4+
limited to).
5+
6+
Copyright (C) Adap.tv, Inc.
7+
8+
RIBS is free software: you can redistribute it and/or modify
9+
it under the terms of the GNU Lesser General Public License as published by
10+
the Free Software Foundation, version 2.1 of the License.
11+
12+
RIBS is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
GNU Lesser General Public License for more details.
16+
17+
You should have received a copy of the GNU Lesser General Public License
18+
along with RIBS. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
#include "timer_worker.h"
21+
#include "ribs.h"
22+
#include <sys/timerfd.h>
23+
24+
struct timer_worker_context {
25+
int tfd;
26+
void (*user_func)(void);
27+
char user_data[];
28+
};
29+
30+
static int _timer_worker_schedule_next(int tfd, time_t usec) {
31+
struct itimerspec timerspec = {{0,0},{usec/1000000,(usec%1000000)*1000}};
32+
if (0 > timerfd_settime(tfd, 0, &timerspec, NULL))
33+
return LOGGER_PERROR("timerfd: %d", tfd), -1;
34+
return 0;
35+
}
36+
37+
static inline struct timer_worker_context *_timer_worker_get_context(void) {
38+
struct timer_worker_context *twc = (struct timer_worker_context *)current_ctx->reserved;
39+
return twc;
40+
}
41+
42+
int timer_worker_schedule_next(time_t usec) {
43+
struct timer_worker_context *twc = _timer_worker_get_context();
44+
return _timer_worker_schedule_next(twc->tfd, usec);
45+
}
46+
47+
static void _timer_worker_wrapper(void) {
48+
struct timer_worker_context *twc = _timer_worker_get_context();
49+
twc->user_func();
50+
}
51+
52+
static void _timer_worker_trigger(void) {
53+
struct ribs_context **worker_ctx_ref = (struct ribs_context **)current_ctx->reserved;
54+
struct ribs_context *worker_ctx = *worker_ctx_ref;
55+
for (;;yield()) {
56+
uint64_t num_exp;
57+
if (sizeof(num_exp) != read(last_epollev.data.fd, &num_exp, sizeof(num_exp))) {
58+
if (EAGAIN == errno)
59+
continue;
60+
abort();
61+
}
62+
ribs_makecontext(worker_ctx, event_loop_ctx, _timer_worker_wrapper);
63+
ribs_swapcurcontext(worker_ctx);
64+
}
65+
}
66+
67+
void *timer_worker_init(size_t stack_size, size_t reserved_size, time_t usec_initial, void (*user_func)(void)) {
68+
int tfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
69+
if (0 > tfd)
70+
return LOGGER_PERROR("timerfd"), NULL;
71+
if (0 > _timer_worker_schedule_next(tfd, usec_initial))
72+
return close(tfd), NULL;
73+
struct ribs_context *ctx = small_ctx_for_fd(tfd, sizeof(struct ribs_context *), _timer_worker_trigger);
74+
struct ribs_context *worker_ctx = ribs_context_create(stack_size, sizeof(struct timer_worker_context) + reserved_size, NULL);
75+
struct ribs_context **ctx_ref = (struct ribs_context **)ctx->reserved;
76+
*ctx_ref = worker_ctx;
77+
struct timer_worker_context *twc = (struct timer_worker_context *)worker_ctx->reserved;
78+
twc->tfd = tfd;
79+
twc->user_func = user_func;
80+
return twc->user_data;
81+
}
82+
83+
void *timer_worker_get_user_data(void) {
84+
struct timer_worker_context *twc = _timer_worker_get_context();
85+
return twc->user_data;
86+
}

0 commit comments

Comments
 (0)