1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 /*  Monkey HTTP Server
4  *  ==================
5  *  Copyright 2001-2017 Eduardo Silva <eduardo@monkey.io>
6  *
7  *  Licensed under the Apache License, Version 2.0 (the "License");
8  *  you may not use this file except in compliance with the License.
9  *  You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *  Unless required by applicable law or agreed to in writing, software
14  *  distributed under the License is distributed on an "AS IS" BASIS,
15  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *  See the License for the specific language governing permissions and
17  *  limitations under the License.
18  */
19 
20 #include <stdint.h>
21 #include "mk_macros.h"
22 #include "mk_list.h"
23 
24 #ifndef MK_EVENT_H
25 #define MK_EVENT_H
26 
27 /* Events type family */
28 #define MK_EVENT_UNMODIFIED     -1    /* keep old event type              */
29 #define MK_EVENT_NOTIFICATION    0    /* notification channel (pipe)      */
30 #define MK_EVENT_LISTENER        1    /* listener socket                  */
31 #define MK_EVENT_FIFO            2    /* FIFO - Messaging                 */
32 #define MK_EVENT_CONNECTION      3    /* data on active connection        */
33 #define MK_EVENT_CUSTOM          4    /* custom fd registered             */
34 #define MK_EVENT_THREAD          5    /* thread-coroutine                 */
35 
36 /* Event triggered for file descriptors  */
37 #define MK_EVENT_EMPTY           0
38 #define MK_EVENT_READ            1
39 #define MK_EVENT_WRITE           4
40 #define MK_EVENT_SLEEP           8
41 #define MK_EVENT_CLOSE          (16 | 8 | 8192)
42 #define MK_EVENT_IDLE           (16 | 8)
43 
44 /* The event queue size */
45 #define MK_EVENT_QUEUE_SIZE    256
46 
47 /* Events behaviors */
48 #define MK_EVENT_LEVEL         256
49 #define MK_EVENT_EDGE          512
50 
51 /* Event status */
52 #define MK_EVENT_NONE            1    /* nothing */
53 #define MK_EVENT_REGISTERED      2    /* event is registered into the ev loop */
54 
55 /* Legacy definitions: temporal
56  *  ----------------------------
57  *
58  * Once a connection is dropped, define
59  * a reason.
60  */
61 #define MK_EP_SOCKET_CLOSED   0
62 #define MK_EP_SOCKET_ERROR    1
63 #define MK_EP_SOCKET_TIMEOUT  2
64 #define MK_EP_SOCKET_DONE     3
65 /* ---- end ---- */
66 
67 #if defined(_WIN32)
68     #include "mk_event_libevent.h"
69 #elif defined(MK_HAVE_EVENT_SELECT)
70     #include "mk_event_select.h"
71 #elif defined(__linux__) && !defined(LINUX_KQUEUE)
72     #include "mk_event_epoll.h"
73 #else
74     #include "mk_event_kqueue.h"
75 #endif
76 
77 #if defined(_WIN32)
78     #define mk_event_closesocket(s) evutil_closesocket(s)
79 #else
80     #define mk_event_closesocket(s) close(s)
81 #endif
82 
83 /* Event reported by the event loop */
84 struct mk_event {
85     int      fd;       /* monitored file descriptor */
86     int      type;     /* event type  */
87     uint32_t mask;     /* events mask */
88     uint8_t  status;   /* internal status */
89     void    *data;     /* custom data reference */
90 
91     /* function handler for custom type */
92     int     (*handler)(void *data);
93     struct mk_list _head;
94 };
95 
96 struct mk_event_loop {
97     int size;                  /* size of events array */
98     int n_events;              /* number of events reported */
99     struct mk_event *events;   /* copy or reference of events triggered */
100     void *data;                /* mk_event_ctx_t from backend */
101 };
102 
103 static inline void MK_EVENT_INIT(struct mk_event *ev, int fd, void *data,
104                                  int (*callback)(void *))
105 {
106     ev->fd      = fd;
107     ev->type    = MK_EVENT_CUSTOM;
108     ev->mask    = MK_EVENT_EMPTY;
109     ev->status  = MK_EVENT_NONE;
110     ev->data    = data;
111     ev->handler = callback;
112 }
113 
114 static inline void MK_EVENT_ZERO(struct mk_event *e)
115 {
116     MK_EVENT_INIT(e, -1, NULL, NULL);
117 }
118 
119 static inline void MK_EVENT_NEW(struct mk_event *e)
120 {
121     e->mask   = MK_EVENT_EMPTY;
122     e->status = MK_EVENT_NONE;
123 }
124 
125 int mk_event_init();
126 int mk_event_initialize();
127 struct mk_event_loop *mk_event_loop_create(int size);
128 void mk_event_loop_destroy(struct mk_event_loop *loop);
129 int mk_event_add(struct mk_event_loop *loop, int fd,
130                  int type, uint32_t mask, void *data);
131 int mk_event_del(struct mk_event_loop *loop, struct mk_event *event);
132 int mk_event_timeout_create(struct mk_event_loop *loop,
133                             time_t sec, long nsec,void *data);
134 int mk_event_timeout_disable(struct mk_event_loop *loop, void *data);
135 int mk_event_timeout_destroy(struct mk_event_loop *loop, void *data);
136 int mk_event_channel_create(struct mk_event_loop *loop,
137                             int *r_fd, int *w_fd, void *data);
138 int mk_event_wait(struct mk_event_loop *loop);
139 int mk_event_translate(struct mk_event_loop *loop);
140 char *mk_event_backend();
141 struct mk_event_fdt *mk_event_get_fdt();
142 
143 #endif
144