aboutsummaryrefslogtreecommitdiffstats
path: root/src/nSocket/include/nstack_eventpoll.h
blob: 1abc0557685587f12a5c92351ff6df3fd8ad8d0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
/*
*
* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
* 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.
*/

#ifndef _NSTACK_EVENTPOOL_H
#define _NSTACK_EVENTPOOL_H

#include "ephlist.h"
#include "eprb_tree.h"
#include "common_mem_api.h"
#include "types.h"
#include <semaphore.h>
#include <sys/epoll.h>
#include <stdio.h>
#include <stdlib.h>
#include "nstack_securec.h"
#include "nstack_log.h"

#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C"{
/* *INDENT-ON* */
#endif /* __cplusplus */

#define NSTACK_MAX_EPOLL_INFO_NUM 8192
#define NSTACK_MAX_EPOLL_NUM NSTACK_MAX_EPOLL_INFO_NUM
#define NSTACK_MAX_EPITEM_NUM (NSTACK_MAX_EPOLL_NUM*2)

#define MP_NSTACK_EPOLL_INFO_NAME "nsep_info"
#define MP_NSTACK_EVENTPOLL_POOL "nsep_eventpoll"       /* Pool of struct eventpoll */
#define MP_NSTACK_EPITEM_POOL "nsep_epitem"     /* Pool of struct epitem */

#define MP_NSTACK_EPINFO_RING_NAME "nsep_info_ring"
#define MP_NSTACK_EPITEM_RING_NAME "nsep_item_ring"
#define MP_NSTACK_EVENTPOOL_RING_NAME "nsep_event_ring"

#define NSTACK_FORK_NUM 32
#define NSTACK_EPOL_FD  1

#define NSEP_SMOD_MAX    8

#define NSEP_EP_UNACTIVE_PTR ((void *) -1L)

COMPAT_PROTECT (NSEP_SMOD_MAX, 8);

typedef struct
{
  u32 pid_used_size;
  u32 pid_array[NSTACK_FORK_NUM];
} nsep_pidinfo;

struct eventpoll
{

  /*
   *    Protect the this structure access
   *    This is for event add to ready list and poll out
   */
  sys_sem_st lock;

  /*
   * This semaphore is used to ensure that files are not removed
   * while epoll is using them. This is read-held during the event
   * processing loop and it is write-held during the file cleanup
   * path, the epoll file exit code and the ctl operations.
   * When we do epoll_ctl, we write lock
   * When we collecting data , we read lock
   */
  sys_sem_st sem;

  /*
   * This sempaphore is used to block epoll_wait function
   */
  sem_t waitSem;

  /* List of ready file descriptors */
  struct ep_hlist rdlist;

  /* When poll data out, we need this list to store tmp epitems */
  struct epitem *ovflist;

  /* RB-Tree root used to store mastered fd structs */
  struct ep_rb_root rbr;

  /* This specifies the file descriptor value of epoll instance, currenlty it is just used for debugging */
  int epfd;
  u32 pid;
  nsfw_res res_chk;
};

struct eventpoll_pool
{
  void *ring;
  struct eventpoll *pool;
};

typedef struct
{
  int iindex;
  int iNext;
  int fd;
  i32 epaddflag;
  i32 fdtype;                   /*0: socket fd, 1: epoll fd */
  i32 rlfd;                     /* copy of fdInf->rlfd */
  i32 rmidx;                    /* copy of fdInf->rmidx */
  i32 protoFD[NSEP_SMOD_MAX];   /* copy of fdInf->protoFD */// Here we need to set router infomations dependency
  struct eventpoll *ep;
  sys_sem_st epiLock;
  sys_sem_st freeLock;
  struct ep_list epiList;       /* This restore the epitem of this file descriptor */
  u32 sleepTime;                //add for NSTACK_SEM_SLEEP
  nsep_pidinfo pidinfo;
  nsfw_res res_chk;
  void *private_data;           /*add for degbu, just used to record extern infomation, for example sbr conn */
  i32 reserv[4];
} nsep_epollInfo_t;

typedef struct
{
  void *ring;
  nsep_epollInfo_t *pool;
  char last_reserve[8];         //reserve for update
} nsep_infoPool_t;

struct epitem
{
  struct ep_rb_node rbn;
  struct ep_hlist_node rdllink;
  struct ep_hlist_node lkFDllink;
  int nwait;
  struct eventpoll *ep;
  nsep_epollInfo_t *epInfo;
  struct epitem *next;
  struct epoll_event event;
  struct list_node fllink;
  unsigned int revents;
  unsigned int ovf_revents;
  int fd;
  u32 pid;
  void *private_data;
  nsfw_res res_chk;
};

struct epitem_pool
{
  void *ring;
  struct epitem *pool;
};

typedef struct
{
  struct eventpoll_pool epollPool;
  struct epitem_pool epitemPool;
  nsep_infoPool_t infoPool;
  nsep_epollInfo_t **infoSockMap;       // The map of epInfo and socket

} nsep_epollManager_t;
extern nsep_epollManager_t g_epollMng;
#define nsep_getManager() (&g_epollMng)

extern int nsep_alloc_eventpoll (struct eventpoll **data);
extern int nsep_free_eventpoll (struct eventpoll *ep);
extern int nsep_alloc_epitem (struct epitem **data);
extern int nsep_free_epitem (struct epitem *data);
extern int nsep_alloc_epinfo (nsep_epollInfo_t ** data);
extern int nsep_free_epinfo (nsep_epollInfo_t * info);

extern int nsep_epitem_remove (nsep_epollInfo_t * pinfo, u32 pid);

extern struct epitem *nsep_find_ep (struct eventpoll *ep, int fd);
extern int nsep_epctl_add (struct eventpoll *ep, int fd,
                           struct epoll_event *events);
extern int nsep_epctl_del (struct eventpoll *ep, struct epitem *epi);
extern int nsep_epctl_mod (struct eventpoll *ep,
                           nsep_epollInfo_t * epInfo,
                           struct epitem *epi, struct epoll_event *events);
extern int nsep_ep_poll (struct eventpoll *ep, struct epoll_event *events,
                         int maxevents, int *eventflag, int num);
extern void nsep_remove_epfd (nsep_epollInfo_t * info);
extern void nsep_close_epfd (struct eventpoll *ep);

/**
 * @Function        nsep_init_infoSockMap
 * @Description     initial map of epoll info and socket
 * @param           none
 * @return          0 on success, -1 on error
 */
extern int nsep_init_infoSockMap ();
extern void nsep_set_infoSockMap (int sock, nsep_epollInfo_t * info);
extern nsep_epollInfo_t *nsep_get_infoBySock (int sock);
extern int nsep_alloc_infoWithSock (int nfd);
extern void nsep_set_infoProtoFD (int fd, int modInx, int protoFD);
extern int nsep_get_infoProtoFD (int fd, int modInx);
extern void nsep_set_infomdix (int fd, int rmidx);
extern int nsep_get_infoMidx (int fd);
extern void nsep_set_infoRlfd (int fd, int rlfd);
extern int nsep_get_infoRlfd (int fd);
extern void nsep_set_infoSleepTime (int fd, u32 sleepTime);
extern int nsep_get_infoSleepTime (int fd);
extern void nsep_set_infoEp (int fd, struct eventpoll *ep);
extern struct eventpoll *nsep_get_infoEp (int fd);
extern int nsep_free_infoWithSock (int sock);
extern int nstack_ep_unlink (struct eventpoll *ep, struct epitem *epi);

/* Attach shared memory */
extern int nsep_create_memory ();
extern int nsep_attach_memory ();
extern int nsep_ep_fdinfo_release (int sock);
extern int nsep_epoll_close (int sock);
extern void nsep_fork_child_proc (u32_t ppid);
extern void nsep_fork_parent_proc (u32_t ppid, u32_t cpid);

static inline i32
nsep_for_pidinfo_init (nsep_pidinfo * pidinfo)
{
  int ret;
  ret = MEMSET_S (pidinfo, sizeof (*pidinfo), 0, sizeof (*pidinfo));
  if (EOK != ret)
    {
      NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret);
      return -1;
    }
  return 0;
}

static inline int
nsep_add_pid (nsep_pidinfo * pidinfo, pid_t pid)
{
  int i;

  for (i = 0; i < NSTACK_FORK_NUM; i++)
    {
      if ((0 == pidinfo->pid_array[i])
          && (__sync_bool_compare_and_swap (&pidinfo->pid_array[i], 0, pid)))
        {
          if (pidinfo->pid_used_size < i + 1)
            {
              pidinfo->pid_used_size = i + 1;
            }
          return 0;
        }
    }
  return -1;
}

static inline int
nsep_del_pid (nsep_pidinfo * pidinfo, pid_t pid)
{
  int i;

  for (i = 0; i < pidinfo->pid_used_size && i < NSTACK_FORK_NUM; i++)
    {
      if (pid == pidinfo->pid_array[i])
        {
          pidinfo->pid_array[i] = 0;
          return 0;
        }
    }
  return -1;
}

static inline int
nsep_del_last_pid (nsep_pidinfo * pidinfo, pid_t pid)
{
  int i;
  int count = 0;
  int deleted = 0;
  for (i = 0; i < pidinfo->pid_used_size && i < NSTACK_FORK_NUM; i++)
    {
      if (pid == pidinfo->pid_array[i])
        {
          pidinfo->pid_array[i] = 0;
          deleted = 1;
          continue;
        }

      if (pidinfo->pid_array[i] != 0)
        {
          ++count;
        }
    }

  if (!deleted)
    {
      return -1;
    }

  return count;
}

static inline int
nsep_is_pid_exist (nsep_pidinfo * epinf, pid_t pid)
{
  int i;

  for (i = 0; i < epinf->pid_used_size && i < NSTACK_FORK_NUM; i++)
    {
      if (pid == epinf->pid_array[i])
        {
          return 1;
        }
    }
  return 0;
}

static inline int
nsep_is_pid_array_empty (nsep_pidinfo * epinf)
{
  int i;
  for (i = 0; i < epinf->pid_used_size && i < NSTACK_FORK_NUM; i++)
    {
      if (epinf->pid_array[i] != 0)
        {
          return 0;
        }
    }
  return 1;
}

#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif /* __cplusplus */

#endif /* _NSTACK_EVENTPOLL_H */