libmemif: memif_control_fd_update always pass context from libmemif_main
[vpp.git] / extras / libmemif / src / main.c
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2017 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17
18 #define _GNU_SOURCE
19 #include <stdint.h>
20 #include <net/if.h>
21 #include <sys/types.h>
22 #include <fcntl.h>
23 #include <sys/ioctl.h>
24 #include <sys/socket.h>
25 #include <sys/un.h>
26 #include <sys/uio.h>
27 #include <sys/mman.h>
28 #include <sys/prctl.h>
29 #include <inttypes.h>
30 #include <string.h>
31 #include <stdio.h>
32 #include <netdb.h>
33 #include <linux/ip.h>
34 #include <linux/icmp.h>
35 #include <arpa/inet.h>
36 #include <stdlib.h>
37 #include <netinet/if_ether.h>
38 #include <net/if_arp.h>
39 #include <asm/byteorder.h>
40 #include <byteswap.h>
41 #include <string.h>
42 #include <errno.h>
43 #include <sys/stat.h>
44 #include <sys/eventfd.h>
45 #include <sys/timerfd.h>
46 #include <sys/epoll.h>
47 #include <signal.h>
48 #include <linux/memfd.h>
49
50 /* memif protocol msg, ring and descriptor definitions */
51 #include <memif.h>
52 /* memif api */
53 #include <libmemif.h>
54 /* socket messaging functions */
55 #include <socket.h>
56 /* private structs and functions */
57 #include <memif_private.h>
58
59 #define ERRLIST_LEN 40
60 #define MAX_ERRBUF_LEN 256
61
62 #if __x86_x64__
63 #define MEMIF_MEMORY_BARRIER() __builtin_ia32_sfence ()
64 #else
65 #define MEMIF_MEMORY_BARRIER() __sync_synchronize ()
66 #endif /* __x86_x64__ */
67
68 libmemif_main_t libmemif_main;
69
70 static char memif_buf[MAX_ERRBUF_LEN];
71
72 const char *memif_errlist[ERRLIST_LEN] = {      /* MEMIF_ERR_SUCCESS */
73   "Success.",
74   /* MEMIF_ERR_SYSCALL */
75   "Unspecified syscall error (build with -DMEMIF_DBG or make debug).",
76   /* MEMIF_ERR_CONNREFUSED */
77   "Connection refused",
78   /* MEMIF_ERR_ACCES */
79   "Permission to resoure denied.",
80   /* MEMIF_ERR_NO_FILE */
81   "Socket file does not exist",
82   /* MEMIF_ERR_FILE_LIMIT */
83   "System limit on total numer of open files reached.",
84   /* MEMIF_ERR_PROC_FILE_LIMIT */
85   "Per-process limit on total number of open files reached.",
86   /* MEMIF_ERR_ALREADY */
87   "Connection already requested.",
88   /* MEMIF_ERR_AGAIN */
89   "File descriptor refers to file other than socket, or operation would block.",
90   /* MEMIF_ERR_BAD_FD */
91   "Bad file descriptor.",
92   /* MEMIF_ERR_NOMEM */
93   "Out of memory.",
94   /* MEMIF_ERR_INVAL_ARG */
95   "Invalid argument.",
96   /* MEMIF_ERR_NOCONN */
97   "Memif connection handle does not point to existing conenction",
98   /* MEMIF_ERR_CONN */
99   "Memif connection handle points to existing connection",
100   /* MEMIF_ERR_CB_FDUPDATE */
101   "Callback memif_control_fd_update_t returned error",
102   /* MEMIF_ERR_FILE_NOT_SOCK */
103   "File specified by socket filename exists and is not socket.",
104   /* MEMIF_ERR_NO_SHMFD */
105   "Missing shared memory file descriptor. (internal error)",
106   /* MEMIF_ERR_COOKIE */
107   "Invalid cookie on ring. (internal error)",
108   /* MEMIF_ERR_NOBUF_RING */
109   "Ring buffer full.",
110   /* MEMIF_ERR_NOBUF */
111   "Not enough memif buffers. There are unreceived data in shared memory.",
112   /* MEMIF_ERR_NOBUF_DET */
113   "Not enough space for memif details in suplied buffer. String data might be malformed.",
114   /* MEMIF_ERR_INT_WRITE */
115   "Send interrupt error.",
116   /* MEMIF_ERR_MFMSG */
117   "Malformed message received on control channel.",
118   /* MEMIF_ERR_QID */
119   "Invalid queue id",
120   /* MEMIF_ERR_PROTO */
121   "Incompatible memory interface protocol version.",
122   /* MEMIF_ERR_ID */
123   "Unmatched interface id.",
124   /* MEMIF_ERR_ACCSLAVE */
125   "Slave cannot accept connection reqest.",
126   /* MEMIF_ERR_ALRCONN */
127   "Interface is already connected.",
128   /* MEMIF_ERR_MODE */
129   "Mode mismatch.",
130   /* MEMIF_ERR_SECRET */
131   "Secret mismatch.",
132   /* MEMIF_ERR_NOSECRET */
133   "Secret required.",
134   /* MEMIF_ERR_MAXREG */
135   "Limit on total number of regions reached.",
136   /* MEMIF_ERR_MAXRING */
137   "Limit on total number of ring reached.",
138   /* MEMIF_ERR_NO_INTFD */
139   "Missing interrupt file descriptor. (internal error)",
140   /* MEMIF_ERR_DISCONNECT */
141   "Interface received disconnect request.",
142   /* MEMIF_ERR_DISCONNECTED */
143   "Interface is disconnected.",
144   /* MEMIF_ERR_UNKNOWN_MSG */
145   "Unknown message type received on control channel. (internal error)",
146   /* MEMIF_ERR_POLL_CANCEL */
147   "Memif event polling was canceled.",
148   /* MEMIF_ERR_MAX_RING */
149   "Maximum log2 ring size is 15",
150   /* MEMIF_ERR_PRIVHDR */
151   "Private headers not supported."
152 };
153
154 #define MEMIF_ERR_UNDEFINED "undefined error"
155
156 char *
157 memif_strerror (int err_code)
158 {
159   if (err_code >= ERRLIST_LEN)
160     {
161       strncpy (memif_buf, MEMIF_ERR_UNDEFINED, strlen (MEMIF_ERR_UNDEFINED));
162       memif_buf[strlen (MEMIF_ERR_UNDEFINED)] = '\0';
163     }
164   else
165     {
166       strncpy (memif_buf, memif_errlist[err_code],
167                strlen (memif_errlist[err_code]));
168       memif_buf[strlen (memif_errlist[err_code])] = '\0';
169     }
170   return memif_buf;
171 }
172
173 uint16_t
174 memif_get_version ()
175 {
176   return MEMIF_VERSION;
177 }
178
179 #define DBG_TX_BUF (0)
180 #define DBG_RX_BUF (1)
181
182 #ifdef MEMIF_DBG_SHM
183 static void
184 print_bytes (void *data, uint16_t len, uint8_t q)
185 {
186   if (q == DBG_TX_BUF)
187     printf ("\nTX:\n\t");
188   else
189     printf ("\nRX:\n\t");
190   int i;
191   for (i = 0; i < len; i++)
192     {
193       if (i % 8 == 0)
194         printf ("\n%d:\t", i);
195       printf ("%02X ", ((uint8_t *) (data))[i]);
196     }
197   printf ("\n\n");
198 }
199 #endif /* MEMIF_DBG_SHM */
200
201 int
202 memif_syscall_error_handler (int err_code)
203 {
204   DBG ("%s", strerror (err_code));
205
206   if (err_code == 0)
207     return MEMIF_ERR_SUCCESS;
208   if (err_code == EACCES)
209     return MEMIF_ERR_ACCES;
210   if (err_code == ENFILE)
211     return MEMIF_ERR_FILE_LIMIT;
212   if (err_code == EMFILE)
213     return MEMIF_ERR_PROC_FILE_LIMIT;
214   if (err_code == ENOMEM)
215     return MEMIF_ERR_NOMEM;
216 /* connection refused if master does not exist
217     this error would spam the user until master was created */
218 /*
219   if (err_code == ECONNREFUSED)
220     return MEMIF_ERR_SUCCESS;
221 */
222   if (err_code == ECONNREFUSED)
223     return MEMIF_ERR_CONNREFUSED;
224   if (err_code == EALREADY)
225     return MEMIF_ERR_ALREADY;
226   if (err_code == EAGAIN)
227     return MEMIF_ERR_AGAIN;
228   if (err_code == EBADF)
229     return MEMIF_ERR_BAD_FD;
230   if (err_code == ENOENT)
231     return MEMIF_ERR_NO_FILE;
232
233   /* other syscall errors */
234   return MEMIF_ERR_SYSCALL;
235 }
236
237 /* Always valid */
238 libmemif_main_t *
239 get_libmemif_main (memif_socket_t * ms)
240 {
241   if (ms != NULL && ms->lm != NULL)
242     return ms->lm;
243   return &libmemif_main;
244 }
245
246 static int
247 memif_add_epoll_fd (libmemif_main_t * lm, int fd, uint32_t events)
248 {
249   if (fd < 0)
250     {
251       DBG ("invalid fd %d", fd);
252       return -1;
253     }
254   struct epoll_event evt;
255   memset (&evt, 0, sizeof (evt));
256   evt.events = events;
257   evt.data.fd = fd;
258   if (epoll_ctl (lm->epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
259     {
260       DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
261       return -1;
262     }
263   DBG ("fd %d added to epoll", fd);
264   return 0;
265 }
266
267 static int
268 memif_mod_epoll_fd (libmemif_main_t * lm, int fd, uint32_t events)
269 {
270   if (fd < 0)
271     {
272       DBG ("invalid fd %d", fd);
273       return -1;
274     }
275   struct epoll_event evt;
276   memset (&evt, 0, sizeof (evt));
277   evt.events = events;
278   evt.data.fd = fd;
279   if (epoll_ctl (lm->epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
280     {
281       DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
282       return -1;
283     }
284   DBG ("fd %d moddified on epoll", fd);
285   return 0;
286 }
287
288 static int
289 memif_del_epoll_fd (libmemif_main_t * lm, int fd)
290 {
291   if (fd < 0)
292     {
293       DBG ("invalid fd %d", fd);
294       return -1;
295     }
296   struct epoll_event evt;
297   memset (&evt, 0, sizeof (evt));
298   if (epoll_ctl (lm->epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
299     {
300       DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
301       return -1;
302     }
303   DBG ("fd %d removed from epoll", fd);
304   return 0;
305 }
306
307 int
308 memif_control_fd_update (int fd, uint8_t events, void *private_ctx)
309 {
310   libmemif_main_t *lm;
311
312   lm = (private_ctx == NULL) ? &libmemif_main : (libmemif_main_t *) private_ctx;
313
314   if (events & MEMIF_FD_EVENT_DEL)
315     return memif_del_epoll_fd (lm, fd);
316
317   uint32_t evt = 0;
318   if (events & MEMIF_FD_EVENT_READ)
319     evt |= EPOLLIN;
320   if (events & MEMIF_FD_EVENT_WRITE)
321     evt |= EPOLLOUT;
322
323   if (events & MEMIF_FD_EVENT_MOD)
324     return memif_mod_epoll_fd (lm, fd, evt);
325
326   return memif_add_epoll_fd (lm, fd, evt);
327 }
328
329 int
330 add_list_elt (libmemif_main_t * lm, memif_list_elt_t * e,
331               memif_list_elt_t ** list, uint16_t * len)
332 {
333   memif_list_elt_t *tmp;
334   int i;
335
336   for (i = 0; i < *len; i++)
337     {
338       if ((*list)[i].data_struct == NULL)
339         {
340           (*list)[i].key = e->key;
341           (*list)[i].data_struct = e->data_struct;
342           return i;
343         }
344     }
345
346   tmp = lm->realloc (*list, sizeof (memif_list_elt_t) * *len * 2);
347   if (tmp == NULL)
348     return -1;
349
350   for (i = *len; i < *len * 2; i++)
351     {
352       tmp[i].key = -1;
353       tmp[i].data_struct = NULL;
354     }
355
356   tmp[*len].key = e->key;
357   tmp[*len].data_struct = e->data_struct;
358   i = *len;
359   *len = *len * 2;
360   *list = tmp;
361
362   return i;
363 }
364
365 int
366 get_list_elt (memif_list_elt_t ** e, memif_list_elt_t * list, uint16_t len,
367               int key)
368 {
369   int i;
370   if (key == -1)
371     {
372       *e = NULL;
373       return -1;
374     }
375
376   for (i = 0; i < len; i++)
377     {
378       if (list[i].key == key)
379         {
380           *e = &list[i];
381           return 0;
382         }
383     }
384   *e = NULL;
385   return -1;
386 }
387
388 /* does not free memory, only marks element as free */
389 int
390 free_list_elt (memif_list_elt_t * list, uint16_t len, int key)
391 {
392   int i;
393   for (i = 0; i < len; i++)
394     {
395       if (list[i].key == key)
396         {
397           list[i].key = -1;
398           list[i].data_struct = NULL;
399           return 0;
400         }
401     }
402
403   return -1;
404 }
405
406 int
407 free_list_elt_ctx (memif_list_elt_t * list, uint16_t len,
408                    memif_connection_t * ctx)
409 {
410   int i;
411   for (i = 0; i < len; i++)
412     {
413       if (list[i].key == -1)
414         {
415           if (list[i].data_struct == ctx)
416             {
417               list[i].data_struct = NULL;
418               return 0;
419             }
420         }
421     }
422
423   return -1;
424 }
425
426 static void
427 memif_control_fd_update_register (libmemif_main_t * lm,
428                                   memif_control_fd_update_t * cb)
429 {
430   lm->control_fd_update = cb;
431 }
432
433 void
434 memif_register_external_region (memif_add_external_region_t * ar,
435                                 memif_get_external_region_addr_t * gr,
436                                 memif_del_external_region_t * dr,
437                                 memif_get_external_buffer_offset_t * go)
438 {
439   libmemif_main_t *lm = &libmemif_main;
440   lm->add_external_region = ar;
441   lm->get_external_region_addr = gr;
442   lm->del_external_region = dr;
443   lm->get_external_buffer_offset = go;
444 }
445
446 static void
447 memif_alloc_register (libmemif_main_t * lm, memif_alloc_t * ma)
448 {
449   lm->alloc = ma;
450 }
451
452 static void
453 memif_realloc_register (libmemif_main_t * lm, memif_realloc_t * mr)
454 {
455   lm->realloc = mr;
456 }
457
458 static void
459 memif_free_register (libmemif_main_t * lm, memif_free_t * mf)
460 {
461   lm->free = mf;
462 }
463
464 int
465 memif_set_connection_request_timer (struct itimerspec timer)
466 {
467   libmemif_main_t *lm = &libmemif_main;
468   int err = MEMIF_ERR_SUCCESS;
469
470   lm->arm = timer;
471
472   /* overwrite timer, if already armed */
473   if (lm->disconn_slaves != 0)
474     {
475       if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
476         {
477           err = memif_syscall_error_handler (errno);
478         }
479     }
480   return err;
481 }
482
483 int
484 memif_per_thread_set_connection_request_timer (memif_per_thread_main_handle_t
485                                                pt_main,
486                                                struct itimerspec timer)
487 {
488   libmemif_main_t *lm = (libmemif_main_t *) pt_main;
489   int err = MEMIF_ERR_SUCCESS;
490
491   lm->arm = timer;
492
493   /* overwrite timer, if already armed */
494   if (lm->disconn_slaves != 0)
495     {
496       if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
497         {
498           err = memif_syscall_error_handler (errno);
499         }
500     }
501   return err;
502 }
503
504 int
505 memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
506             memif_alloc_t * memif_alloc, memif_realloc_t * memif_realloc,
507             memif_free_t * memif_free)
508 {
509   int err = MEMIF_ERR_SUCCESS;  /* 0 */
510   libmemif_main_t *lm = &libmemif_main;
511   memset (lm, 0, sizeof (libmemif_main_t));
512
513   /* register custom memory management */
514   if (memif_alloc != NULL)
515     {
516       memif_alloc_register (lm, memif_alloc);
517     }
518   else
519     memif_alloc_register (lm, malloc);
520
521   if (memif_realloc != NULL)
522     {
523       memif_realloc_register (lm, memif_realloc);
524     }
525   else
526     memif_realloc_register (lm, realloc);
527
528   if (memif_free != NULL)
529     memif_free_register (lm, memif_free);
530   else
531     memif_free_register (lm, free);
532
533   if (app_name != NULL)
534     {
535       uint8_t len = (strlen (app_name) > MEMIF_NAME_LEN)
536         ? strlen (app_name) : MEMIF_NAME_LEN;
537       strncpy ((char *) lm->app_name, app_name, len);
538     }
539   else
540     {
541       strncpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
542                strlen (MEMIF_DEFAULT_APP_NAME));
543     }
544
545   lm->poll_cancel_fd = -1;
546   /* register control fd update callback */
547   if (on_control_fd_update != NULL)
548     memif_control_fd_update_register (lm, on_control_fd_update);
549   else
550     {
551       lm->epfd = epoll_create (1);
552       memif_control_fd_update_register (lm, memif_control_fd_update);
553       if ((lm->poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
554         {
555           err = errno;
556           DBG ("eventfd: %s", strerror (err));
557           return memif_syscall_error_handler (err);
558         }
559       lm->control_fd_update (lm->poll_cancel_fd, MEMIF_FD_EVENT_READ, lm->private_ctx);
560       DBG ("libmemif event polling initialized");
561     }
562
563   lm->control_list_len = 2;
564   lm->interrupt_list_len = 2;
565   lm->socket_list_len = 1;
566   lm->pending_list_len = 1;
567
568   lm->control_list =
569     lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
570   if (lm->control_list == NULL)
571     {
572       err = MEMIF_ERR_NOMEM;
573       goto error;
574     }
575   lm->interrupt_list =
576     lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
577   if (lm->interrupt_list == NULL)
578     {
579       err = MEMIF_ERR_NOMEM;
580       goto error;
581     }
582   lm->socket_list =
583     lm->alloc (sizeof (memif_list_elt_t) * lm->socket_list_len);
584   if (lm->socket_list == NULL)
585     {
586       err = MEMIF_ERR_NOMEM;
587       goto error;
588     }
589   lm->pending_list =
590     lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
591   if (lm->pending_list == NULL)
592     {
593       err = MEMIF_ERR_NOMEM;
594       goto error;
595     }
596
597   int i;
598   for (i = 0; i < lm->control_list_len; i++)
599     {
600       lm->control_list[i].key = -1;
601       lm->control_list[i].data_struct = NULL;
602     }
603   for (i = 0; i < lm->interrupt_list_len; i++)
604     {
605       lm->interrupt_list[i].key = -1;
606       lm->interrupt_list[i].data_struct = NULL;
607     }
608   for (i = 0; i < lm->socket_list_len; i++)
609     {
610       lm->socket_list[i].key = -1;
611       lm->socket_list[i].data_struct = NULL;
612     }
613   for (i = 0; i < lm->pending_list_len; i++)
614     {
615       lm->pending_list[i].key = -1;
616       lm->pending_list[i].data_struct = NULL;
617     }
618
619   lm->disconn_slaves = 0;
620
621   lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
622   if (lm->timerfd < 0)
623     {
624       err = memif_syscall_error_handler (errno);
625       goto error;
626     }
627
628   lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
629   lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
630   lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
631   lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
632
633   if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ, lm->private_ctx) < 0)
634     {
635       DBG ("callback type memif_control_fd_update_t error!");
636       err = MEMIF_ERR_CB_FDUPDATE;
637       goto error;
638     }
639
640   /* Create default socket */
641   err = memif_create_socket ((memif_socket_handle_t *) &
642                              lm->default_socket,
643                              MEMIF_DEFAULT_SOCKET_PATH, NULL);
644   if (err != MEMIF_ERR_SUCCESS)
645     goto error;
646
647   return err;
648
649 error:
650   memif_cleanup ();
651   return err;
652 }
653
654 int
655 memif_per_thread_init (memif_per_thread_main_handle_t * pt_main,
656                        void *private_ctx,
657                        memif_control_fd_update_t * on_control_fd_update,
658                        char *app_name, memif_alloc_t * memif_alloc,
659                        memif_realloc_t * memif_realloc,
660                        memif_free_t * memif_free)
661 {
662   memif_err_t err = MEMIF_ERR_SUCCESS;
663   int i;
664   libmemif_main_t *lm;
665
666   /* Allocate unique libmemif main */
667   if (memif_alloc != NULL)
668     lm = memif_alloc (sizeof (libmemif_main_t));
669   else
670     lm = malloc (sizeof (libmemif_main_t));
671
672   if (lm == NULL)
673     return MEMIF_ERR_NOMEM;
674
675   memset (lm, 0, sizeof (libmemif_main_t));
676
677   /* register custom memory management */
678   if (memif_alloc != NULL)
679     {
680       memif_alloc_register (lm, memif_alloc);
681     }
682   else
683     memif_alloc_register (lm, malloc);
684
685   if (memif_realloc != NULL)
686     {
687       memif_realloc_register (lm, memif_realloc);
688     }
689   else
690     memif_realloc_register (lm, realloc);
691
692   if (memif_free != NULL)
693     memif_free_register (lm, memif_free);
694   else
695     memif_free_register (lm, free);
696
697   lm->private_ctx = private_ctx;
698
699   /* set app name */
700   if (app_name != NULL)
701     {
702       uint8_t len = (strlen (app_name) > MEMIF_NAME_LEN)
703         ? strlen (app_name) : MEMIF_NAME_LEN;
704       strncpy ((char *) lm->app_name, app_name, len);
705     }
706   else
707     {
708       strncpy ((char *) lm->app_name, MEMIF_DEFAULT_APP_NAME,
709                strlen (MEMIF_DEFAULT_APP_NAME));
710     }
711
712   lm->poll_cancel_fd = -1;
713   /* register control fd update callback */
714   if (on_control_fd_update != NULL)
715     memif_control_fd_update_register (lm, on_control_fd_update);
716   else
717     {
718       /* private_ctx only used internally by memif_control_fd_update
719        * pointer to this libmemif main
720        */
721       lm->private_ctx = lm;
722       lm->epfd = epoll_create (1);
723       memif_control_fd_update_register (lm, memif_control_fd_update);
724       if ((lm->poll_cancel_fd = eventfd (0, EFD_NONBLOCK)) < 0)
725         {
726           err = errno;
727           DBG ("eventfd: %s", strerror (err));
728           return memif_syscall_error_handler (err);
729         }
730       lm->control_fd_update (lm->poll_cancel_fd, MEMIF_FD_EVENT_READ,
731                              lm->private_ctx);
732       DBG ("libmemif event polling initialized");
733     }
734
735   /* Initialize lists */
736   lm->control_list_len = 2;
737   lm->interrupt_list_len = 2;
738   lm->socket_list_len = 1;
739   lm->pending_list_len = 1;
740
741   lm->control_list =
742     lm->alloc (sizeof (memif_list_elt_t) * lm->control_list_len);
743   if (lm->control_list == NULL)
744     {
745       err = MEMIF_ERR_NOMEM;
746       goto error;
747     }
748   lm->interrupt_list =
749     lm->alloc (sizeof (memif_list_elt_t) * lm->interrupt_list_len);
750   if (lm->interrupt_list == NULL)
751     {
752       err = MEMIF_ERR_NOMEM;
753       goto error;
754     }
755   lm->socket_list =
756     lm->alloc (sizeof (memif_list_elt_t) * lm->socket_list_len);
757   if (lm->socket_list == NULL)
758     {
759       err = MEMIF_ERR_NOMEM;
760       goto error;
761     }
762   lm->pending_list =
763     lm->alloc (sizeof (memif_list_elt_t) * lm->pending_list_len);
764   if (lm->pending_list == NULL)
765     {
766       err = MEMIF_ERR_NOMEM;
767       goto error;
768     }
769
770   for (i = 0; i < lm->control_list_len; i++)
771     {
772       lm->control_list[i].key = -1;
773       lm->control_list[i].data_struct = NULL;
774     }
775   for (i = 0; i < lm->interrupt_list_len; i++)
776     {
777       lm->interrupt_list[i].key = -1;
778       lm->interrupt_list[i].data_struct = NULL;
779     }
780   for (i = 0; i < lm->socket_list_len; i++)
781     {
782       lm->socket_list[i].key = -1;
783       lm->socket_list[i].data_struct = NULL;
784     }
785   for (i = 0; i < lm->pending_list_len; i++)
786     {
787       lm->pending_list[i].key = -1;
788       lm->pending_list[i].data_struct = NULL;
789     }
790
791   /* Initialize autoconnect */
792   lm->disconn_slaves = 0;
793
794   lm->timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK);
795   if (lm->timerfd < 0)
796     {
797       err = memif_syscall_error_handler (errno);
798       goto error;
799     }
800
801   lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
802   lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
803   lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
804   lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
805
806   if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ,
807                              lm->private_ctx) < 0)
808     {
809       DBG ("callback type memif_control_fd_update_t error!");
810       err = MEMIF_ERR_CB_FDUPDATE;
811       goto error;
812     }
813
814   *pt_main = lm;
815
816   return err;
817
818 error:
819   *pt_main = lm;
820   memif_per_thread_cleanup (pt_main);
821   return err;
822 }
823
824 static inline memif_ring_t *
825 memif_get_ring (memif_connection_t * conn, memif_ring_type_t type,
826                 uint16_t ring_num)
827 {
828   if (&conn->regions[0] == NULL)
829     return NULL;
830   void *p = conn->regions[0].addr;
831   int ring_size =
832     sizeof (memif_ring_t) +
833     sizeof (memif_desc_t) * (1 << conn->run_args.log2_ring_size);
834   p += (ring_num + type * conn->run_args.num_s2m_rings) * ring_size;
835
836   return (memif_ring_t *) p;
837 }
838
839 int
840 memif_set_rx_mode (memif_conn_handle_t c, memif_rx_mode_t rx_mode,
841                    uint16_t qid)
842 {
843   memif_connection_t *conn = (memif_connection_t *) c;
844   if (conn == NULL)
845     return MEMIF_ERR_NOCONN;
846   uint8_t num =
847     (conn->args.is_master) ? conn->run_args.num_s2m_rings : conn->
848     run_args.num_m2s_rings;
849   if (qid >= num)
850     return MEMIF_ERR_QID;
851
852   conn->rx_queues[qid].ring->flags = rx_mode;
853   DBG ("rx_mode flag: %u", conn->rx_queues[qid].ring->flags);
854   return MEMIF_ERR_SUCCESS;
855 }
856
857 static int
858 memif_socket_start_listening (memif_socket_t * ms)
859 {
860   libmemif_main_t *lm = get_libmemif_main (ms);
861   memif_list_elt_t elt;
862   struct stat file_stat;
863   struct sockaddr_un un = { 0 };
864   int on = 1;
865   int err = MEMIF_ERR_SUCCESS;
866
867   if (ms->type == MEMIF_SOCKET_TYPE_CLIENT)
868     return MEMIF_ERR_INVAL_ARG;
869
870   /* check if file exists */
871   if (stat ((char *) ms->filename, &file_stat) == 0)
872     {
873       if (S_ISSOCK (file_stat.st_mode))
874         unlink ((char *) ms->filename);
875       else
876         return memif_syscall_error_handler (errno);
877     }
878
879   ms->fd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
880   if (ms->fd < 0)
881     {
882       err = memif_syscall_error_handler (errno);
883       goto error;
884     }
885
886   DBG ("socket %d created", ms->fd);
887   un.sun_family = AF_UNIX;
888   strncpy ((char *) un.sun_path, (char *) ms->filename,
889            sizeof (un.sun_path) - 1);
890   if (setsockopt (ms->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
891     {
892       err = memif_syscall_error_handler (errno);
893       goto error;
894     }
895   if (bind (ms->fd, (struct sockaddr *) &un, sizeof (un)) < 0)
896     {
897       err = memif_syscall_error_handler (errno);
898       goto error;
899     }
900   if (listen (ms->fd, 1) < 0)
901     {
902       err = memif_syscall_error_handler (errno);
903       goto error;
904     }
905   if (stat ((char *) ms->filename, &file_stat) < 0)
906     {
907       err = memif_syscall_error_handler (errno);
908       goto error;
909     }
910
911   /* add socket to libmemif main */
912   elt.key = ms->fd;
913   elt.data_struct = ms;
914   add_list_elt (lm, &elt, &lm->socket_list, &lm->socket_list_len);
915   /* if lm->private_ctx == lm event polling is done by libmemif */
916   lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_READ, lm->private_ctx);
917
918   ms->type = MEMIF_SOCKET_TYPE_LISTENER;
919
920   return err;
921
922 error:
923   if (ms->fd > 0)
924     {
925       close (ms->fd);
926       ms->fd = -1;
927     }
928   return err;
929 }
930
931 int
932 memif_create_socket (memif_socket_handle_t * sock, const char *filename,
933                      void *private_ctx)
934 {
935   libmemif_main_t *lm = &libmemif_main;
936   memif_socket_t *ms = (memif_socket_t *) * sock;
937   int i, err = MEMIF_ERR_SUCCESS;
938
939   for (i = 0; i < lm->socket_list_len; i++)
940     {
941       if ((ms = (memif_socket_t *) lm->socket_list[i].data_struct) != NULL)
942         {
943           if (strncmp ((char *) ms->filename, filename,
944                        strlen ((char *) ms->filename)) == 0)
945             return MEMIF_ERR_INVAL_ARG;
946         }
947     }
948
949   /* allocate memif_socket_t */
950   ms = NULL;
951   ms = lm->alloc (sizeof (memif_socket_t));
952   if (ms == NULL)
953     {
954       err = MEMIF_ERR_NOMEM;
955       goto error;
956     }
957   memset (ms, 0, sizeof (memif_socket_t));
958   /* set filename */
959   ms->filename = lm->alloc (strlen (filename) + sizeof (char));
960   if (ms->filename == NULL)
961     {
962       err = MEMIF_ERR_NOMEM;
963       goto error;
964     }
965   memset (ms->filename, 0, strlen (filename) + sizeof (char));
966   strncpy ((char *) ms->filename, filename, strlen (filename));
967
968   ms->type = MEMIF_SOCKET_TYPE_NONE;
969
970   ms->interface_list_len = 1;
971   ms->interface_list =
972     lm->alloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
973   if (ms->interface_list == NULL)
974     {
975       err = MEMIF_ERR_NOMEM;
976       goto error;
977     }
978   ms->interface_list[0].key = -1;
979   ms->interface_list[0].data_struct = NULL;
980
981   *sock = ms;
982
983   return err;
984
985 error:
986   if (ms != NULL)
987     {
988       if (ms->filename != NULL)
989         {
990           lm->free (ms->filename);
991           ms->filename = NULL;
992         }
993       if (ms->fd > 0)
994         {
995           close (ms->fd);
996           ms->fd = -1;
997         }
998       if (ms->interface_list != NULL)
999         {
1000           lm->free (ms->interface_list);
1001           ms->interface_list = NULL;
1002           ms->interface_list_len = 0;
1003         }
1004       lm->free (ms);
1005       *sock = ms = NULL;
1006     }
1007   return err;
1008 }
1009
1010 int
1011 memif_per_thread_create_socket (memif_per_thread_main_handle_t pt_main,
1012                                 memif_socket_handle_t * sock,
1013                                 const char *filename, void *private_ctx)
1014 {
1015   libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1016   memif_socket_t *ms = (memif_socket_t *) * sock;
1017   int i, err = MEMIF_ERR_SUCCESS;
1018
1019   if (lm == NULL)
1020     return MEMIF_ERR_INVAL_ARG;
1021
1022   for (i = 0; i < lm->socket_list_len; i++)
1023     {
1024       if ((ms = (memif_socket_t *) lm->socket_list[i].data_struct) != NULL)
1025         {
1026           if (strncmp ((char *) ms->filename, filename,
1027                        strlen ((char *) ms->filename)) == 0)
1028             return MEMIF_ERR_INVAL_ARG;
1029         }
1030     }
1031
1032   /* allocate memif_socket_t */
1033   ms = NULL;
1034   ms = lm->alloc (sizeof (memif_socket_t));
1035   if (ms == NULL)
1036     {
1037       err = MEMIF_ERR_NOMEM;
1038       goto error;
1039     }
1040   memset (ms, 0, sizeof (memif_socket_t));
1041   ms->lm = lm;
1042   /* set filename */
1043   ms->filename = lm->alloc (strlen (filename) + sizeof (char));
1044   if (ms->filename == NULL)
1045     {
1046       err = MEMIF_ERR_NOMEM;
1047       goto error;
1048     }
1049   memset (ms->filename, 0, strlen (filename) + sizeof (char));
1050   strncpy ((char *) ms->filename, filename, strlen (filename));
1051
1052   ms->type = MEMIF_SOCKET_TYPE_NONE;
1053
1054   ms->interface_list_len = 1;
1055   ms->interface_list =
1056     lm->alloc (sizeof (memif_list_elt_t) * ms->interface_list_len);
1057   if (ms->interface_list == NULL)
1058     {
1059       err = MEMIF_ERR_NOMEM;
1060       goto error;
1061     }
1062   ms->interface_list[0].key = -1;
1063   ms->interface_list[0].data_struct = NULL;
1064
1065   *sock = ms;
1066
1067   return err;
1068
1069 error:
1070   if (ms != NULL)
1071     {
1072       if (ms->filename != NULL)
1073         {
1074           lm->free (ms->filename);
1075           ms->filename = NULL;
1076         }
1077       if (ms->fd > 0)
1078         {
1079           close (ms->fd);
1080           ms->fd = -1;
1081         }
1082       if (ms->interface_list != NULL)
1083         {
1084           lm->free (ms->interface_list);
1085           ms->interface_list = NULL;
1086           ms->interface_list_len = 0;
1087         }
1088       lm->free (ms);
1089       *sock = ms = NULL;
1090     }
1091   return err;
1092 }
1093
1094 int
1095 memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
1096               memif_connection_update_t * on_connect,
1097               memif_connection_update_t * on_disconnect,
1098               memif_interrupt_t * on_interrupt, void *private_ctx)
1099 {
1100   libmemif_main_t *lm = get_libmemif_main (args->socket);
1101   int err, index = 0;
1102   memif_list_elt_t elt;
1103   memif_connection_t *conn = (memif_connection_t *) * c;
1104   memif_socket_t *ms;
1105
1106   if (conn != NULL)
1107     {
1108       DBG ("This handle already points to existing memif.");
1109       return MEMIF_ERR_CONN;
1110     }
1111
1112   conn = (memif_connection_t *) lm->alloc (sizeof (memif_connection_t));
1113   if (conn == NULL)
1114     {
1115       err = MEMIF_ERR_NOMEM;
1116       goto error;
1117     }
1118   memset (conn, 0, sizeof (memif_connection_t));
1119
1120   conn->args.interface_id = args->interface_id;
1121
1122   if (args->log2_ring_size == 0)
1123     args->log2_ring_size = MEMIF_DEFAULT_LOG2_RING_SIZE;
1124   else if (args->log2_ring_size > MEMIF_MAX_LOG2_RING_SIZE)
1125     {
1126       err = MEMIF_ERR_MAX_RING;
1127       goto error;
1128     }
1129   if (args->buffer_size == 0)
1130     args->buffer_size = MEMIF_DEFAULT_BUFFER_SIZE;
1131   if (args->num_s2m_rings == 0)
1132     args->num_s2m_rings = MEMIF_DEFAULT_TX_QUEUES;
1133   if (args->num_m2s_rings == 0)
1134     args->num_m2s_rings = MEMIF_DEFAULT_RX_QUEUES;
1135
1136   conn->args.num_s2m_rings = args->num_s2m_rings;
1137   conn->args.num_m2s_rings = args->num_m2s_rings;
1138   conn->args.buffer_size = args->buffer_size;
1139   conn->args.log2_ring_size = args->log2_ring_size;
1140   conn->args.is_master = args->is_master;
1141   conn->args.mode = args->mode;
1142   conn->msg_queue = NULL;
1143   conn->regions = NULL;
1144   conn->tx_queues = NULL;
1145   conn->rx_queues = NULL;
1146   conn->fd = -1;
1147   conn->on_connect = on_connect;
1148   conn->on_disconnect = on_disconnect;
1149   conn->on_interrupt = on_interrupt;
1150   conn->private_ctx = private_ctx;
1151   memset (&conn->run_args, 0, sizeof (memif_conn_run_args_t));
1152
1153   uint8_t l = strlen ((char *) args->interface_name);
1154   strncpy ((char *) conn->args.interface_name, (char *) args->interface_name,
1155            l);
1156
1157   if ((l = strlen ((char *) args->secret)) > 0)
1158     strncpy ((char *) conn->args.secret, (char *) args->secret, l);
1159
1160   if (args->socket != NULL)
1161     conn->args.socket = args->socket;
1162   else if (lm->default_socket != NULL)
1163     conn->args.socket = lm->default_socket;
1164   else
1165     {
1166       err = MEMIF_ERR_INVAL_ARG;
1167       goto error;
1168     }
1169
1170   ms = (memif_socket_t *) conn->args.socket;
1171
1172   if ((conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_CLIENT) ||
1173       (!conn->args.is_master && ms->type == MEMIF_SOCKET_TYPE_LISTENER))
1174     {
1175       err = MEMIF_ERR_INVAL_ARG;
1176       goto error;
1177     }
1178
1179   elt.key = conn->args.interface_id;
1180   elt.data_struct = conn;
1181   add_list_elt (lm, &elt, &ms->interface_list, &ms->interface_list_len);
1182   ms->use_count++;
1183
1184   if (conn->args.is_master)
1185     {
1186       if (ms->type == MEMIF_SOCKET_TYPE_NONE)
1187         {
1188           err = memif_socket_start_listening (ms);
1189           if (err != MEMIF_ERR_SUCCESS)
1190             goto error;
1191         }
1192     }
1193   else
1194     {
1195       elt.key = -1;
1196       elt.data_struct = conn;
1197       if ((index =
1198            add_list_elt (lm, &elt, &lm->control_list,
1199                          &lm->control_list_len)) < 0)
1200         {
1201           err = MEMIF_ERR_NOMEM;
1202           goto error;
1203         }
1204
1205       conn->index = index;
1206
1207       /* try connectiong to master */
1208       err = memif_request_connection (conn);
1209       if ((err != MEMIF_ERR_SUCCESS) && (lm->disconn_slaves == 0))
1210         {
1211           /* connection failed, arm reconnect timer (if not armed) */
1212           if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1213             {
1214               err = memif_syscall_error_handler (errno);
1215               goto error;
1216             }
1217         }
1218       lm->disconn_slaves++;
1219     }
1220
1221   *c = conn;
1222
1223   return 0;
1224
1225 error:
1226   if (conn != NULL)
1227     lm->free (conn);
1228   *c = conn = NULL;
1229   return err;
1230 }
1231
1232 int
1233 memif_request_connection (memif_conn_handle_t c)
1234 {
1235   memif_connection_t *conn = (memif_connection_t *) c;
1236   libmemif_main_t *lm;
1237   memif_socket_t *ms;
1238   int err = MEMIF_ERR_SUCCESS;
1239   int sockfd = -1;
1240   struct sockaddr_un sun;
1241
1242   if (conn == NULL)
1243     return MEMIF_ERR_NOCONN;
1244
1245   ms = (memif_socket_t *) conn->args.socket;
1246   lm = get_libmemif_main (ms);
1247
1248
1249   if (conn->args.is_master || ms->type == MEMIF_SOCKET_TYPE_LISTENER)
1250     return MEMIF_ERR_INVAL_ARG;
1251   if (conn->fd > 0)
1252     return MEMIF_ERR_ALRCONN;
1253
1254   sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
1255   if (sockfd < 0)
1256     {
1257       err = memif_syscall_error_handler (errno);
1258       goto error;
1259     }
1260
1261   sun.sun_family = AF_UNIX;
1262
1263   strncpy (sun.sun_path, (char *) ms->filename, sizeof (sun.sun_path) - 1);
1264
1265   if (connect (sockfd, (struct sockaddr *) &sun,
1266                sizeof (struct sockaddr_un)) == 0)
1267     {
1268       conn->fd = sockfd;
1269       conn->read_fn = memif_conn_fd_read_ready;
1270       conn->write_fn = memif_conn_fd_write_ready;
1271       conn->error_fn = memif_conn_fd_error;
1272
1273       lm->control_list[conn->index].key = conn->fd;
1274       lm->control_fd_update (sockfd,
1275                              MEMIF_FD_EVENT_READ |
1276                              MEMIF_FD_EVENT_WRITE, lm->private_ctx);
1277
1278       lm->disconn_slaves--;
1279       if (lm->disconn_slaves == 0)
1280         {
1281           if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1282             {
1283               err = memif_syscall_error_handler (errno);
1284               return err;
1285             }
1286         }
1287     }
1288   else
1289     {
1290       err = memif_syscall_error_handler (errno);
1291       strcpy ((char *) conn->remote_disconnect_string, memif_strerror (err));
1292       goto error;
1293     }
1294
1295   ms->type = MEMIF_SOCKET_TYPE_CLIENT;
1296
1297   return err;
1298
1299 error:
1300   if (sockfd > 0)
1301     close (sockfd);
1302   sockfd = -1;
1303   return err;
1304 }
1305
1306 int
1307 memif_control_fd_handler (int fd, uint8_t events)
1308 {
1309   int i, err = MEMIF_ERR_SUCCESS;       /* 0 */
1310   uint16_t num;
1311   memif_list_elt_t *e = NULL;
1312   memif_connection_t *conn;
1313   libmemif_main_t *lm = &libmemif_main;
1314   if (fd == lm->timerfd)
1315     {
1316       uint64_t b;
1317       ssize_t size;
1318       size = read (fd, &b, sizeof (b));
1319
1320       if (size == -1)
1321         goto error;
1322
1323       for (i = 0; i < lm->control_list_len; i++)
1324         {
1325           if ((lm->control_list[i].key < 0)
1326               && (lm->control_list[i].data_struct != NULL))
1327             {
1328               conn = lm->control_list[i].data_struct;
1329               if (conn->args.is_master)
1330                 continue;
1331               err = memif_request_connection (conn);
1332               if (err != MEMIF_ERR_SUCCESS)
1333                 DBG ("memif_request_connection: %s", memif_strerror (err));
1334             }
1335         }
1336     }
1337   else
1338     {
1339       get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
1340       if (e != NULL)
1341         {
1342           if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
1343             {
1344               num =
1345                 (((memif_connection_t *) e->data_struct)->
1346                  args.is_master) ? ((memif_connection_t *) e->
1347                                     data_struct)->run_args.
1348                 num_s2m_rings : ((memif_connection_t *) e->data_struct)->
1349                 run_args.num_m2s_rings;
1350               for (i = 0; i < num; i++)
1351                 {
1352                   if (((memif_connection_t *) e->data_struct)->
1353                       rx_queues[i].int_fd == fd)
1354                     {
1355                       ((memif_connection_t *) e->data_struct)->
1356                         on_interrupt ((void *) e->data_struct,
1357                                       ((memif_connection_t *) e->
1358                                        data_struct)->private_ctx, i);
1359                       return MEMIF_ERR_SUCCESS;
1360                     }
1361                 }
1362             }
1363           return MEMIF_ERR_SUCCESS;
1364         }
1365       get_list_elt (&e, lm->socket_list, lm->socket_list_len, fd);
1366       if (e != NULL
1367           && ((memif_socket_t *) e->data_struct)->type ==
1368           MEMIF_SOCKET_TYPE_LISTENER)
1369         {
1370           err =
1371             memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
1372           return err;
1373         }
1374
1375       get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
1376       if (e != NULL)
1377         {
1378           err = memif_read_ready (lm, fd);
1379           return err;
1380         }
1381
1382       get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
1383       if (e != NULL)
1384         {
1385           if (events & MEMIF_FD_EVENT_READ)
1386             {
1387               err =
1388                 ((memif_connection_t *) e->data_struct)->
1389                 read_fn (e->data_struct);
1390               if (err != MEMIF_ERR_SUCCESS)
1391                 return err;
1392             }
1393           if (events & MEMIF_FD_EVENT_WRITE)
1394             {
1395               err =
1396                 ((memif_connection_t *) e->data_struct)->
1397                 write_fn (e->data_struct);
1398               if (err != MEMIF_ERR_SUCCESS)
1399                 return err;
1400             }
1401           if (events & MEMIF_FD_EVENT_ERROR)
1402             {
1403               err =
1404                 ((memif_connection_t *) e->data_struct)->
1405                 error_fn (e->data_struct);
1406               if (err != MEMIF_ERR_SUCCESS)
1407                 return err;
1408             }
1409         }
1410     }
1411
1412   return MEMIF_ERR_SUCCESS;     /* 0 */
1413
1414 error:
1415   return err;
1416 }
1417
1418 int
1419 memif_per_thread_control_fd_handler (memif_per_thread_main_handle_t pt_main,
1420                                      int fd, uint8_t events)
1421 {
1422   int i, err = MEMIF_ERR_SUCCESS;       /* 0 */
1423   uint16_t num;
1424   memif_list_elt_t *e = NULL;
1425   memif_connection_t *conn;
1426   libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1427
1428   if (fd == lm->timerfd)
1429     {
1430       uint64_t b;
1431       ssize_t size;
1432       size = read (fd, &b, sizeof (b));
1433
1434       if (size == -1)
1435         goto error;
1436
1437       for (i = 0; i < lm->control_list_len; i++)
1438         {
1439           if ((lm->control_list[i].key < 0)
1440               && (lm->control_list[i].data_struct != NULL))
1441             {
1442               conn = lm->control_list[i].data_struct;
1443               if (conn->args.is_master)
1444                 continue;
1445               err = memif_request_connection (conn);
1446               if (err != MEMIF_ERR_SUCCESS)
1447                 DBG ("memif_request_connection: %s", memif_strerror (err));
1448             }
1449         }
1450     }
1451   else
1452     {
1453       get_list_elt (&e, lm->interrupt_list, lm->interrupt_list_len, fd);
1454       if (e != NULL)
1455         {
1456           if (((memif_connection_t *) e->data_struct)->on_interrupt != NULL)
1457             {
1458               num =
1459                 (((memif_connection_t *) e->data_struct)->
1460                  args.is_master) ? ((memif_connection_t *) e->
1461                                     data_struct)->run_args.
1462                 num_s2m_rings : ((memif_connection_t *) e->data_struct)->
1463                 run_args.num_m2s_rings;
1464               for (i = 0; i < num; i++)
1465                 {
1466                   if (((memif_connection_t *) e->data_struct)->
1467                       rx_queues[i].int_fd == fd)
1468                     {
1469                       ((memif_connection_t *) e->data_struct)->
1470                         on_interrupt ((void *) e->data_struct,
1471                                       ((memif_connection_t *) e->
1472                                        data_struct)->private_ctx, i);
1473                       return MEMIF_ERR_SUCCESS;
1474                     }
1475                 }
1476             }
1477           return MEMIF_ERR_SUCCESS;
1478         }
1479       get_list_elt (&e, lm->socket_list, lm->socket_list_len, fd);
1480       if (e != NULL
1481           && ((memif_socket_t *) e->data_struct)->type ==
1482           MEMIF_SOCKET_TYPE_LISTENER)
1483         {
1484           err =
1485             memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
1486           return err;
1487         }
1488
1489       get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
1490       if (e != NULL)
1491         {
1492           err = memif_read_ready (lm, fd);
1493           return err;
1494         }
1495
1496       get_list_elt (&e, lm->control_list, lm->control_list_len, fd);
1497       if (e != NULL)
1498         {
1499           if (events & MEMIF_FD_EVENT_READ)
1500             {
1501               err =
1502                 ((memif_connection_t *) e->data_struct)->
1503                 read_fn (e->data_struct);
1504               if (err != MEMIF_ERR_SUCCESS)
1505                 return err;
1506             }
1507           if (events & MEMIF_FD_EVENT_WRITE)
1508             {
1509               err =
1510                 ((memif_connection_t *) e->data_struct)->
1511                 write_fn (e->data_struct);
1512               if (err != MEMIF_ERR_SUCCESS)
1513                 return err;
1514             }
1515           if (events & MEMIF_FD_EVENT_ERROR)
1516             {
1517               err =
1518                 ((memif_connection_t *) e->data_struct)->
1519                 error_fn (e->data_struct);
1520               if (err != MEMIF_ERR_SUCCESS)
1521                 return err;
1522             }
1523         }
1524     }
1525
1526   return MEMIF_ERR_SUCCESS;     /* 0 */
1527
1528 error:
1529   return err;
1530 }
1531
1532 int
1533 memif_poll_event (int timeout)
1534 {
1535   libmemif_main_t *lm = &libmemif_main;
1536   struct epoll_event evt;
1537   int en = 0, err = MEMIF_ERR_SUCCESS;  /* 0 */
1538   uint32_t events = 0;
1539   uint64_t counter = 0;
1540   ssize_t r = 0;
1541   memset (&evt, 0, sizeof (evt));
1542   evt.events = EPOLLIN | EPOLLOUT;
1543   sigset_t sigset;
1544   sigemptyset (&sigset);
1545   en = epoll_pwait (lm->epfd, &evt, 1, timeout, &sigset);
1546   if (en < 0)
1547     {
1548       err = errno;
1549       DBG ("epoll_pwait: %s", strerror (err));
1550       return memif_syscall_error_handler (err);
1551     }
1552   if (en > 0)
1553     {
1554       if (evt.data.fd == lm->poll_cancel_fd)
1555         {
1556           r = read (evt.data.fd, &counter, sizeof (counter));
1557           if (r == -1)
1558             return MEMIF_ERR_DISCONNECTED;
1559
1560           return MEMIF_ERR_POLL_CANCEL;
1561         }
1562       if (evt.events & EPOLLIN)
1563         events |= MEMIF_FD_EVENT_READ;
1564       if (evt.events & EPOLLOUT)
1565         events |= MEMIF_FD_EVENT_WRITE;
1566       if (evt.events & EPOLLERR)
1567         events |= MEMIF_FD_EVENT_ERROR;
1568       err = memif_control_fd_handler (evt.data.fd, events);
1569       return err;
1570     }
1571   return 0;
1572 }
1573
1574 int
1575 memif_per_thread_poll_event (memif_per_thread_main_handle_t pt_main,
1576                              int timeout)
1577 {
1578   libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1579   struct epoll_event evt;
1580   int en = 0, err = MEMIF_ERR_SUCCESS;  /* 0 */
1581   uint32_t events = 0;
1582   uint64_t counter = 0;
1583   ssize_t r = 0;
1584   memset (&evt, 0, sizeof (evt));
1585   evt.events = EPOLLIN | EPOLLOUT;
1586   sigset_t sigset;
1587   sigemptyset (&sigset);
1588   en = epoll_pwait (lm->epfd, &evt, 1, timeout, &sigset);
1589   if (en < 0)
1590     {
1591       err = errno;
1592       DBG ("epoll_pwait: %s", strerror (err));
1593       return memif_syscall_error_handler (err);
1594     }
1595   if (en > 0)
1596     {
1597       if (evt.data.fd == lm->poll_cancel_fd)
1598         {
1599           r = read (evt.data.fd, &counter, sizeof (counter));
1600           if (r == -1)
1601             return MEMIF_ERR_DISCONNECTED;
1602
1603           return MEMIF_ERR_POLL_CANCEL;
1604         }
1605       if (evt.events & EPOLLIN)
1606         events |= MEMIF_FD_EVENT_READ;
1607       if (evt.events & EPOLLOUT)
1608         events |= MEMIF_FD_EVENT_WRITE;
1609       if (evt.events & EPOLLERR)
1610         events |= MEMIF_FD_EVENT_ERROR;
1611       err = memif_control_fd_handler (evt.data.fd, events);
1612       return err;
1613     }
1614   return 0;
1615 }
1616
1617 int
1618 memif_cancel_poll_event ()
1619 {
1620   libmemif_main_t *lm = &libmemif_main;
1621   uint64_t counter = 1;
1622   ssize_t w = 0;
1623
1624   if (lm->poll_cancel_fd == -1)
1625     return 0;
1626   w = write (lm->poll_cancel_fd, &counter, sizeof (counter));
1627   if (w < sizeof (counter))
1628     return MEMIF_ERR_INT_WRITE;
1629
1630   return 0;
1631 }
1632
1633 int
1634 memif_per_thread_cancel_poll_event (memif_per_thread_main_handle_t pt_main)
1635 {
1636   libmemif_main_t *lm = (libmemif_main_t *) pt_main;
1637   uint64_t counter = 1;
1638   ssize_t w = 0;
1639
1640   if (lm == NULL)
1641     return MEMIF_ERR_INVAL_ARG;
1642
1643   if (lm->poll_cancel_fd == -1)
1644     return 0;
1645   w = write (lm->poll_cancel_fd, &counter, sizeof (counter));
1646   if (w < sizeof (counter))
1647     return MEMIF_ERR_INT_WRITE;
1648
1649   return 0;
1650 }
1651
1652 static void
1653 memif_msg_queue_free (libmemif_main_t * lm, memif_msg_queue_elt_t ** e)
1654 {
1655   if (*e == NULL)
1656     return;
1657   memif_msg_queue_free (lm, &(*e)->next);
1658   lm->free (*e);
1659   *e = NULL;
1660   return;
1661 }
1662
1663 /* send disconnect msg and close interface */
1664 int
1665 memif_disconnect_internal (memif_connection_t * c)
1666 {
1667   int err = MEMIF_ERR_SUCCESS, i;       /* 0 */
1668   memif_queue_t *mq;
1669   libmemif_main_t *lm;
1670   memif_list_elt_t *e;
1671
1672   if (c == NULL)
1673     {
1674       DBG ("no connection");
1675       return MEMIF_ERR_NOCONN;
1676     }
1677
1678   lm = get_libmemif_main (c->args.socket);
1679
1680   c->on_disconnect ((void *) c, c->private_ctx);
1681
1682   if (c->fd > 0)
1683     {
1684       memif_msg_send_disconnect (c->fd, (uint8_t *) "interface deleted", 0);
1685       lm->control_fd_update (c->fd, MEMIF_FD_EVENT_DEL, lm->private_ctx);
1686       close (c->fd);
1687     }
1688   get_list_elt (&e, lm->control_list, lm->control_list_len, c->fd);
1689   if (e != NULL)
1690     {
1691       if (c->args.is_master)
1692         free_list_elt (lm->control_list, lm->control_list_len, c->fd);
1693       e->key = c->fd = -1;
1694     }
1695
1696   if (c->tx_queues != NULL)
1697     {
1698       for (i = 0; i < c->tx_queues_num; i++)
1699         {
1700           mq = &c->tx_queues[i];
1701           if (mq != NULL)
1702             {
1703               if (mq->int_fd > 0)
1704                 close (mq->int_fd);
1705               free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
1706                              mq->int_fd);
1707               mq->int_fd = -1;
1708             }
1709         }
1710       lm->free (c->tx_queues);
1711       c->tx_queues = NULL;
1712     }
1713   c->tx_queues_num = 0;
1714
1715   if (c->rx_queues != NULL)
1716     {
1717       for (i = 0; i < c->rx_queues_num; i++)
1718         {
1719           mq = &c->rx_queues[i];
1720           if (mq != NULL)
1721             {
1722               if (mq->int_fd > 0)
1723                 {
1724                   if (c->on_interrupt != NULL)
1725                     lm->control_fd_update (mq->int_fd, MEMIF_FD_EVENT_DEL,
1726                                            lm->private_ctx);
1727                   close (mq->int_fd);
1728                 }
1729               free_list_elt (lm->interrupt_list, lm->interrupt_list_len,
1730                              mq->int_fd);
1731               mq->int_fd = -1;
1732             }
1733         }
1734       lm->free (c->rx_queues);
1735       c->rx_queues = NULL;
1736     }
1737   c->rx_queues_num = 0;
1738
1739   for (i = 0; i < c->regions_num; i++)
1740     {
1741       if (&c->regions[i] == NULL)
1742         continue;
1743       if (c->regions[i].is_external != 0)
1744         {
1745           lm->del_external_region (c->regions[i].addr,
1746                                    c->regions[i].region_size,
1747                                    c->regions[i].fd, c->private_ctx);
1748         }
1749       else
1750         {
1751           if (munmap (c->regions[i].addr, c->regions[i].region_size) < 0)
1752             return memif_syscall_error_handler (errno);
1753           if (c->regions[i].fd > 0)
1754             close (c->regions[i].fd);
1755           c->regions[i].fd = -1;
1756         }
1757     }
1758   lm->free (c->regions);
1759   c->regions = NULL;
1760   c->regions_num = 0;
1761
1762   memset (&c->run_args, 0, sizeof (memif_conn_run_args_t));
1763
1764   memif_msg_queue_free (lm, &c->msg_queue);
1765
1766   if (!(c->args.is_master))
1767     {
1768       if (lm->disconn_slaves == 0)
1769         {
1770           if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0)
1771             {
1772               err = memif_syscall_error_handler (errno);
1773               DBG ("timerfd_settime: arm");
1774             }
1775         }
1776       lm->disconn_slaves++;
1777     }
1778
1779   return err;
1780 }
1781
1782 const char *
1783 memif_get_socket_filename (memif_socket_handle_t sock)
1784 {
1785   memif_socket_t *ms = (memif_socket_t *) sock;
1786
1787   if (ms == NULL)
1788     return NULL;
1789
1790   return (char *) ms->filename;
1791 }
1792
1793 int
1794 memif_delete_socket (memif_socket_handle_t * sock)
1795 {
1796   memif_socket_t *ms = (memif_socket_t *) * sock;
1797   libmemif_main_t *lm;
1798
1799   /* check if socket is in use */
1800   if (ms == NULL || ms->use_count > 0)
1801     return MEMIF_ERR_INVAL_ARG;
1802
1803   lm = get_libmemif_main (ms);
1804
1805   lm->free (ms->interface_list);
1806   ms->interface_list = NULL;
1807   lm->free (ms->filename);
1808   ms->filename = NULL;
1809   lm->free (ms);
1810   *sock = ms = NULL;
1811
1812   return MEMIF_ERR_SUCCESS;
1813 }
1814
1815 int
1816 memif_delete (memif_conn_handle_t * conn)
1817 {
1818   memif_connection_t *c = (memif_connection_t *) * conn;
1819   libmemif_main_t *lm;
1820   memif_socket_t *ms = NULL;
1821   int err = MEMIF_ERR_SUCCESS;
1822
1823   if (c == NULL)
1824     {
1825       DBG ("no connection");
1826       return MEMIF_ERR_NOCONN;
1827     }
1828
1829   if (c->fd > 0)
1830     {
1831       DBG ("DISCONNECTING");
1832       err = memif_disconnect_internal (c);
1833       if (err == MEMIF_ERR_NOCONN)
1834         return err;
1835     }
1836
1837   lm = get_libmemif_main (c->args.socket);
1838
1839   free_list_elt_ctx (lm->control_list, lm->control_list_len, c);
1840
1841   ms = (memif_socket_t *) c->args.socket;
1842   ms->use_count--;
1843   free_list_elt (ms->interface_list, ms->interface_list_len,
1844                  c->args.interface_id);
1845   if (ms->use_count <= 0)
1846     {
1847       /* stop listening on this socket */
1848       if (ms->type == MEMIF_SOCKET_TYPE_LISTENER)
1849         {
1850           lm->control_fd_update (ms->fd, MEMIF_FD_EVENT_DEL, lm->private_ctx);
1851           free_list_elt (lm->socket_list, lm->socket_list_len, ms->fd);
1852           close (ms->fd);
1853           ms->fd = -1;
1854         }
1855       /* socket not in use */
1856       ms->type = MEMIF_SOCKET_TYPE_NONE;
1857     }
1858
1859   if (!c->args.is_master)
1860     {
1861       lm->disconn_slaves--;
1862       if (lm->disconn_slaves <= 0)
1863         {
1864           if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0)
1865             {
1866               err = memif_syscall_error_handler (errno);
1867               DBG ("timerfd_settime: disarm");
1868             }
1869         }
1870     }
1871
1872   lm->free (c);
1873   c = NULL;
1874
1875   *conn = c;
1876   return err;
1877 }
1878
1879 int
1880 memif_connect1 (memif_connection_t * c)
1881 {
1882   libmemif_main_t *lm;
1883   memif_region_t *mr;
1884   memif_queue_t *mq;
1885   int i;
1886
1887   if (c == NULL)
1888     return MEMIF_ERR_INVAL_ARG;
1889
1890   lm = get_libmemif_main (c->args.socket);
1891
1892   for (i = 0; i < c->regions_num; i++)
1893     {
1894       mr = &c->regions[i];
1895       if (mr != NULL)
1896         {
1897           if (!mr->addr)
1898             {
1899               if (mr->is_external)
1900                 {
1901                   if (lm->get_external_region_addr == NULL)
1902                     return MEMIF_ERR_INVAL_ARG;
1903                   mr->addr =
1904                     lm->get_external_region_addr (mr->region_size, mr->fd,
1905                                                   c->private_ctx);
1906                 }
1907               else
1908                 {
1909                   if (mr->fd < 0)
1910                     return MEMIF_ERR_NO_SHMFD;
1911
1912                   if ((mr->addr =
1913                        mmap (NULL, mr->region_size, PROT_READ | PROT_WRITE,
1914                              MAP_SHARED, mr->fd, 0)) == MAP_FAILED)
1915                     {
1916                       return memif_syscall_error_handler (errno);
1917                     }
1918                 }
1919             }
1920         }
1921     }
1922
1923   for (i = 0; i < c->rx_queues_num; i++)
1924     {
1925       mq = &c->rx_queues[i];
1926       if (mq != NULL)
1927         {
1928           mq->ring = c->regions[mq->region].addr + mq->offset;
1929           if (mq->ring->cookie != MEMIF_COOKIE)
1930             {
1931               DBG ("wrong cookie on rx ring %u", i);
1932               return MEMIF_ERR_COOKIE;
1933             }
1934           mq->ring->head = mq->ring->tail = mq->last_head = mq->alloc_bufs =
1935             0;
1936         }
1937     }
1938
1939   for (i = 0; i < c->tx_queues_num; i++)
1940     {
1941       mq = &c->tx_queues[i];
1942       if (mq != NULL)
1943         {
1944           mq->ring = c->regions[mq->region].addr + mq->offset;
1945           if (mq->ring->cookie != MEMIF_COOKIE)
1946             {
1947               DBG ("wrong cookie on tx ring %u", i);
1948               return MEMIF_ERR_COOKIE;
1949             }
1950           mq->ring->head = mq->ring->tail = mq->last_head = mq->alloc_bufs =
1951             0;
1952         }
1953     }
1954
1955   lm->control_fd_update (c->fd, MEMIF_FD_EVENT_READ | MEMIF_FD_EVENT_MOD,
1956                          lm->private_ctx);
1957
1958   return 0;
1959 }
1960
1961 static inline int
1962 memif_add_region (libmemif_main_t * lm, memif_connection_t * conn,
1963                   uint8_t has_buffers)
1964 {
1965   memif_region_t *r;
1966
1967   r =
1968     lm->realloc (conn->regions,
1969                  sizeof (memif_region_t) * ++conn->regions_num);
1970   if (r == NULL)
1971     return MEMIF_ERR_NOMEM;
1972
1973   conn->regions = r;
1974   r = &conn->regions[conn->regions_num - 1];
1975   memset (r, 0, sizeof (memif_region_t));
1976
1977   if (has_buffers != 0)
1978     {
1979       r->buffer_offset = 0;
1980     }
1981   else
1982     {
1983       r->buffer_offset =
1984         (conn->run_args.num_s2m_rings +
1985          conn->run_args.num_m2s_rings) * (sizeof (memif_ring_t) +
1986                                           sizeof (memif_desc_t) *
1987                                           (1 << conn->
1988                                            run_args.log2_ring_size));
1989     }
1990
1991   r->region_size = (has_buffers == 0) ? r->buffer_offset : r->buffer_offset +
1992     conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
1993     (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
1994
1995   if ((r->fd = memfd_create ("memif region 0", MFD_ALLOW_SEALING)) == -1)
1996     return memif_syscall_error_handler (errno);
1997
1998   if ((fcntl (r->fd, F_ADD_SEALS, F_SEAL_SHRINK)) == -1)
1999     return memif_syscall_error_handler (errno);
2000
2001   if ((ftruncate (r->fd, r->region_size)) == -1)
2002     return memif_syscall_error_handler (errno);
2003
2004   if ((r->addr = mmap (NULL, r->region_size, PROT_READ | PROT_WRITE,
2005                        MAP_SHARED, r->fd, 0)) == MAP_FAILED)
2006     return memif_syscall_error_handler (errno);
2007
2008   return MEMIF_ERR_SUCCESS;
2009 }
2010
2011 static inline int
2012 memif_init_queues (libmemif_main_t * lm, memif_connection_t * conn)
2013 {
2014   int i, j;
2015   memif_ring_t *ring;
2016
2017   for (i = 0; i < conn->run_args.num_s2m_rings; i++)
2018     {
2019       ring = memif_get_ring (conn, MEMIF_RING_S2M, i);
2020       DBG ("RING: %p I: %d", ring, i);
2021       ring->head = ring->tail = 0;
2022       ring->cookie = MEMIF_COOKIE;
2023       ring->flags = 0;
2024       for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
2025         {
2026           uint16_t slot = i * (1 << conn->run_args.log2_ring_size) + j;
2027           ring->desc[j].region = 1;
2028           ring->desc[j].offset =
2029             conn->regions[1].buffer_offset +
2030             (uint32_t) (slot * conn->run_args.buffer_size);
2031           ring->desc[j].length = conn->run_args.buffer_size;
2032         }
2033     }
2034   for (i = 0; i < conn->run_args.num_m2s_rings; i++)
2035     {
2036       ring = memif_get_ring (conn, MEMIF_RING_M2S, i);
2037       DBG ("RING: %p I: %d", ring, i);
2038       ring->head = ring->tail = 0;
2039       ring->cookie = MEMIF_COOKIE;
2040       ring->flags = 0;
2041       for (j = 0; j < (1 << conn->run_args.log2_ring_size); j++)
2042         {
2043           uint16_t slot = (i + conn->run_args.num_s2m_rings) *
2044             (1 << conn->run_args.log2_ring_size) + j;
2045           ring->desc[j].region = 1;
2046           ring->desc[j].offset =
2047             conn->regions[1].buffer_offset +
2048             (uint32_t) (slot * conn->run_args.buffer_size);
2049           ring->desc[j].length = conn->run_args.buffer_size;
2050         }
2051     }
2052   memif_queue_t *mq;
2053   DBG ("alloc: %p", lm->alloc);
2054   DBG ("size: %lu", sizeof (memif_queue_t) * conn->run_args.num_s2m_rings);
2055   mq =
2056     (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
2057                                  conn->run_args.num_s2m_rings);
2058   if (mq == NULL)
2059     return MEMIF_ERR_NOMEM;
2060
2061   int x;
2062   memif_list_elt_t e;
2063   for (x = 0; x < conn->run_args.num_s2m_rings; x++)
2064     {
2065       if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2066         return memif_syscall_error_handler (errno);
2067       e.key = mq[x].int_fd;
2068       e.data_struct = conn;
2069       add_list_elt (lm, &e, &lm->interrupt_list, &lm->interrupt_list_len);
2070
2071       mq[x].ring = memif_get_ring (conn, MEMIF_RING_S2M, x);
2072       DBG ("RING: %p I: %d", mq[x].ring, x);
2073       mq[x].log2_ring_size = conn->run_args.log2_ring_size;
2074       mq[x].region = 0;
2075       mq[x].offset =
2076         (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
2077       mq[x].last_head = mq[x].last_tail = 0;
2078       mq[x].alloc_bufs = 0;
2079     }
2080   conn->tx_queues = mq;
2081   conn->tx_queues_num = conn->run_args.num_s2m_rings;
2082
2083   mq =
2084     (memif_queue_t *) lm->alloc (sizeof (memif_queue_t) *
2085                                  conn->run_args.num_m2s_rings);
2086   if (mq == NULL)
2087     return MEMIF_ERR_NOMEM;
2088
2089   for (x = 0; x < conn->run_args.num_m2s_rings; x++)
2090     {
2091       if ((mq[x].int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
2092         return memif_syscall_error_handler (errno);
2093       e.key = mq[x].int_fd;
2094       e.data_struct = conn;
2095       add_list_elt (lm, &e, &lm->interrupt_list, &lm->interrupt_list_len);
2096
2097       mq[x].ring = memif_get_ring (conn, MEMIF_RING_M2S, x);
2098       DBG ("RING: %p I: %d", mq[x].ring, x);
2099       mq[x].log2_ring_size = conn->run_args.log2_ring_size;
2100       mq[x].region = 0;
2101       mq[x].offset =
2102         (void *) mq[x].ring - (void *) conn->regions[mq->region].addr;
2103       mq[x].last_head = mq[x].last_tail = 0;
2104       mq[x].alloc_bufs = 0;
2105     }
2106   conn->rx_queues = mq;
2107   conn->rx_queues_num = conn->run_args.num_m2s_rings;
2108
2109   return MEMIF_ERR_SUCCESS;
2110 }
2111
2112 int
2113 memif_init_regions_and_queues (memif_connection_t * conn)
2114 {
2115   memif_region_t *r;
2116   libmemif_main_t *lm;
2117
2118   if (conn == NULL)
2119     return MEMIF_ERR_INVAL_ARG;
2120
2121   lm = get_libmemif_main (conn->args.socket);
2122
2123   /* region 0. rings */
2124   memif_add_region (lm, conn, /* has_buffers */ 0);
2125
2126   /* region 1. buffers */
2127   if (lm->add_external_region)
2128     {
2129       r =
2130         (memif_region_t *) lm->realloc (conn->regions,
2131                                         sizeof (memif_region_t) *
2132                                         ++conn->regions_num);
2133       if (r == NULL)
2134         return MEMIF_ERR_NOMEM;
2135       conn->regions = r;
2136
2137       conn->regions[1].region_size =
2138         conn->run_args.buffer_size * (1 << conn->run_args.log2_ring_size) *
2139         (conn->run_args.num_s2m_rings + conn->run_args.num_m2s_rings);
2140       conn->regions[1].buffer_offset = 0;
2141       lm->add_external_region (&conn->regions[1].addr,
2142                                conn->regions[1].region_size,
2143                                &conn->regions[1].fd, conn->private_ctx);
2144       conn->regions[1].is_external = 1;
2145     }
2146   else
2147     {
2148       memif_add_region (lm, conn, 1);
2149     }
2150
2151   memif_init_queues (lm, conn);
2152
2153   return 0;
2154 }
2155
2156 int
2157 memif_buffer_enq_tx (memif_conn_handle_t conn, uint16_t qid,
2158                      memif_buffer_t * bufs, uint16_t count,
2159                      uint16_t * count_out)
2160 {
2161   memif_connection_t *c = (memif_connection_t *) conn;
2162   if (EXPECT_FALSE (c == NULL))
2163     return MEMIF_ERR_NOCONN;
2164   if (EXPECT_FALSE (c->fd < 0))
2165     return MEMIF_ERR_DISCONNECTED;
2166   uint8_t num =
2167     (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2168     run_args.num_s2m_rings;
2169   if (EXPECT_FALSE (qid >= num))
2170     return MEMIF_ERR_QID;
2171   if (EXPECT_FALSE (!count_out))
2172     return MEMIF_ERR_INVAL_ARG;
2173   if (EXPECT_FALSE (c->args.is_master))
2174     return MEMIF_ERR_INVAL_ARG;
2175
2176   memif_queue_t *mq = &c->tx_queues[qid];
2177   memif_ring_t *ring = mq->ring;
2178   memif_buffer_t *b0;
2179   uint16_t mask = (1 << mq->log2_ring_size) - 1;
2180   uint16_t ring_size;
2181   uint16_t slot, ns;
2182   int err = MEMIF_ERR_SUCCESS;  /* 0 */
2183   *count_out = 0;
2184
2185   ring_size = (1 << mq->log2_ring_size);
2186   slot = (c->args.is_master) ? ring->tail : ring->head;
2187   slot += mq->alloc_bufs;
2188
2189   /* can only be called by slave */
2190   ns = ring_size - (ring->head + mq->alloc_bufs) + ring->tail;
2191
2192   b0 = bufs;
2193
2194   while (count && ns)
2195     {
2196       if (EXPECT_FALSE ((b0->flags & MEMIF_BUFFER_FLAG_RX) == 0))
2197         {
2198           /* not a valid buffer */
2199           count--;
2200           continue;
2201         }
2202       b0->flags &= ~MEMIF_BUFFER_FLAG_RX;
2203
2204       ((memif_ring_t *) b0->ring)->desc[b0->desc_index & mask].offset = ring->desc[slot & mask].offset; /* put free buffer on rx ring */
2205
2206       ring->desc[slot & mask].offset =
2207         (uint32_t) (b0->data -
2208                     c->regions[ring->desc[slot & mask].region].addr);
2209       ring->desc[slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
2210       ring->desc[slot & mask].flags |=
2211         (b0->flags & MEMIF_BUFFER_FLAG_NEXT) ? MEMIF_DESC_FLAG_NEXT : 0;
2212
2213       b0->desc_index = slot;
2214
2215       mq->alloc_bufs++;
2216       slot++;
2217
2218       count--;
2219       ns--;
2220       b0++;
2221       *count_out += 1;
2222     }
2223
2224   DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
2225        mq->alloc_bufs);
2226
2227   if (count)
2228     {
2229       DBG ("ring buffer full! qid: %u", qid);
2230       err = MEMIF_ERR_NOBUF_RING;
2231     }
2232
2233   return err;
2234 }
2235
2236 int
2237 memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
2238                     memif_buffer_t * bufs, uint16_t count,
2239                     uint16_t * count_out, uint16_t size)
2240 {
2241   memif_connection_t *c = (memif_connection_t *) conn;
2242   if (EXPECT_FALSE (c == NULL))
2243     return MEMIF_ERR_NOCONN;
2244   if (EXPECT_FALSE (c->fd < 0))
2245     return MEMIF_ERR_DISCONNECTED;
2246   uint8_t num =
2247     (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2248     run_args.num_s2m_rings;
2249   if (EXPECT_FALSE (qid >= num))
2250     return MEMIF_ERR_QID;
2251   if (EXPECT_FALSE (!count_out))
2252     return MEMIF_ERR_INVAL_ARG;
2253
2254   libmemif_main_t *lm = get_libmemif_main (c->args.socket);
2255   memif_queue_t *mq = &c->tx_queues[qid];
2256   memif_ring_t *ring = mq->ring;
2257   memif_buffer_t *b0;
2258   uint16_t mask = (1 << mq->log2_ring_size) - 1;
2259   uint32_t offset_mask = c->run_args.buffer_size - 1;
2260   uint16_t ring_size;
2261   uint16_t slot, ns;
2262   int err = MEMIF_ERR_SUCCESS;  /* 0 */
2263   uint16_t dst_left, src_left;
2264   uint16_t saved_count;
2265   memif_buffer_t *saved_b;
2266   *count_out = 0;
2267
2268   ring_size = (1 << mq->log2_ring_size);
2269   slot = (c->args.is_master) ? ring->tail : ring->head;
2270   slot += mq->alloc_bufs;
2271
2272   if (c->args.is_master)
2273     ns = ring->head - (ring->tail + mq->alloc_bufs);
2274   else
2275     ns = ring_size - (ring->head + mq->alloc_bufs) + ring->tail;
2276
2277   while (count && ns)
2278     {
2279       b0 = (bufs + *count_out);
2280
2281       saved_b = b0;
2282       saved_count = count;
2283
2284       b0->desc_index = slot;
2285       ring->desc[slot & mask].flags = 0;
2286
2287       /* slave can produce buffer with original length */
2288       dst_left = (c->args.is_master) ? ring->desc[slot & mask].length :
2289         c->run_args.buffer_size;
2290       src_left = size;
2291
2292       while (src_left)
2293         {
2294           if (EXPECT_FALSE (dst_left == 0))
2295             {
2296               if (count && ns)
2297                 {
2298                   slot++;
2299                   *count_out += 1;
2300                   mq->alloc_bufs++;
2301                   ns--;
2302
2303                   ring->desc[b0->desc_index & mask].flags |=
2304                     MEMIF_DESC_FLAG_NEXT;
2305                   b0->flags |= MEMIF_BUFFER_FLAG_NEXT;
2306
2307                   b0 = (bufs + *count_out);
2308                   b0->desc_index = slot;
2309                   dst_left =
2310                     (c->args.is_master) ? ring->desc[slot & mask].
2311                     length : c->run_args.buffer_size;
2312                   ring->desc[slot & mask].flags = 0;
2313                 }
2314               else
2315                 {
2316                   /* rollback allocated chain buffers */
2317                   memset (saved_b, 0, sizeof (memif_buffer_t)
2318                           * (saved_count - count + 1));
2319                   *count_out -= saved_count - count;
2320                   mq->alloc_bufs = saved_count - count;
2321                   goto no_ns;
2322                 }
2323             }
2324           b0->len = memif_min (dst_left, src_left);
2325
2326           /* slave resets buffer offset */
2327           if (c->args.is_master == 0)
2328             {
2329               memif_desc_t *d = &ring->desc[slot & mask];
2330               if (lm->get_external_buffer_offset)
2331                 d->offset = lm->get_external_buffer_offset (c->private_ctx);
2332               else
2333                 d->offset = d->offset - (d->offset & offset_mask);
2334             }
2335           b0->data = memif_get_buffer (c, ring, slot & mask);
2336
2337           src_left -= b0->len;
2338           dst_left -= b0->len;
2339         }
2340
2341       slot++;
2342       *count_out += 1;
2343       mq->alloc_bufs++;
2344       ns--;
2345       count--;
2346     }
2347
2348 no_ns:
2349
2350   DBG ("allocated: %u/%u bufs. Total %u allocated bufs", *count_out, count,
2351        mq->alloc_bufs);
2352
2353   if (count)
2354     {
2355       DBG ("ring buffer full! qid: %u", qid);
2356       err = MEMIF_ERR_NOBUF_RING;
2357     }
2358
2359   return err;
2360 }
2361
2362 int
2363 memif_refill_queue (memif_conn_handle_t conn, uint16_t qid, uint16_t count,
2364                     uint16_t headroom)
2365 {
2366   memif_connection_t *c = (memif_connection_t *) conn;
2367   if (EXPECT_FALSE (c == NULL))
2368     return MEMIF_ERR_NOCONN;
2369   if (EXPECT_FALSE (c->fd < 0))
2370     return MEMIF_ERR_DISCONNECTED;
2371   uint8_t num =
2372     (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2373     run_args.num_m2s_rings;
2374   if (EXPECT_FALSE (qid >= num))
2375     return MEMIF_ERR_QID;
2376   libmemif_main_t *lm = get_libmemif_main (c->args.socket);
2377   memif_queue_t *mq = &c->rx_queues[qid];
2378   memif_ring_t *ring = mq->ring;
2379   uint16_t mask = (1 << mq->log2_ring_size) - 1;
2380   uint32_t offset_mask = c->run_args.buffer_size - 1;
2381   uint16_t slot;
2382
2383   if (c->args.is_master)
2384     {
2385       MEMIF_MEMORY_BARRIER ();
2386       ring->tail =
2387         (ring->tail + count <=
2388          mq->last_head) ? ring->tail + count : mq->last_head;
2389       return MEMIF_ERR_SUCCESS;
2390     }
2391
2392   uint16_t head = ring->head;
2393   uint16_t ns = (1 << mq->log2_ring_size) - head + mq->last_tail;
2394   head += (count < ns) ? count : ns;
2395
2396   slot = ring->head;
2397   memif_desc_t *d;
2398   while (slot < head)
2399     {
2400       d = &ring->desc[slot & mask];
2401       d->region = 1;
2402       d->length = c->run_args.buffer_size - headroom;
2403       if (lm->get_external_buffer_offset)
2404         d->offset = lm->get_external_buffer_offset (c->private_ctx);
2405       else
2406         d->offset = d->offset - (d->offset & offset_mask) + headroom;
2407       slot++;
2408     }
2409
2410   MEMIF_MEMORY_BARRIER ();
2411   ring->head = head;
2412
2413   return MEMIF_ERR_SUCCESS;     /* 0 */
2414 }
2415
2416 int
2417 memif_tx_burst (memif_conn_handle_t conn, uint16_t qid,
2418                 memif_buffer_t * bufs, uint16_t count, uint16_t * tx)
2419 {
2420   memif_connection_t *c = (memif_connection_t *) conn;
2421   if (EXPECT_FALSE (c == NULL))
2422     return MEMIF_ERR_NOCONN;
2423   if (EXPECT_FALSE (c->fd < 0))
2424     return MEMIF_ERR_DISCONNECTED;
2425   uint8_t num =
2426     (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2427     run_args.num_s2m_rings;
2428   if (EXPECT_FALSE (qid >= num))
2429     return MEMIF_ERR_QID;
2430   if (EXPECT_FALSE (!tx))
2431     return MEMIF_ERR_INVAL_ARG;
2432
2433   memif_queue_t *mq = &c->tx_queues[qid];
2434   memif_ring_t *ring = mq->ring;
2435   uint16_t mask = (1 << mq->log2_ring_size) - 1;
2436   memif_buffer_t *b0;
2437   *tx = 0;
2438
2439   if (count > mq->alloc_bufs)
2440     count = mq->alloc_bufs;
2441
2442   if (EXPECT_FALSE (count == 0))
2443     return MEMIF_ERR_SUCCESS;
2444
2445   while (count)
2446     {
2447       b0 = (bufs + *tx);
2448       ring->desc[b0->desc_index & mask].length = b0->len;
2449
2450 #ifdef MEMIF_DBG_SHM
2451       printf ("offset: %-6d\n", ring->desc[b0->desc_index & mask].offset);
2452       printf ("data: %p\n",
2453               memif_get_buffer (c, ring, b0->desc_index & mask));
2454       printf ("index: %u\n", b0->desc_index);
2455       print_bytes (memif_get_buffer (c, ring, b0->desc_index & mask),
2456                    ring->desc[b0->desc_index & mask].length, DBG_TX_BUF);
2457 #endif /* MEMIF_DBG_SHM */
2458
2459       *tx += 1;
2460       count--;
2461     }
2462
2463
2464   MEMIF_MEMORY_BARRIER ();
2465   if (c->args.is_master)
2466     ring->tail = b0->desc_index + 1;
2467   else
2468     ring->head = b0->desc_index + 1;
2469
2470   mq->alloc_bufs -= *tx;
2471
2472   if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
2473     {
2474       uint64_t a = 1;
2475       int r = write (mq->int_fd, &a, sizeof (a));
2476       if (r < 0)
2477         return MEMIF_ERR_INT_WRITE;
2478     }
2479
2480   return MEMIF_ERR_SUCCESS;     /* 0 */
2481 }
2482
2483 int
2484 memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
2485                 memif_buffer_t * bufs, uint16_t count, uint16_t * rx)
2486 {
2487   memif_connection_t *c = (memif_connection_t *) conn;
2488   if (EXPECT_FALSE (c == NULL))
2489     return MEMIF_ERR_NOCONN;
2490   if (EXPECT_FALSE (c->fd < 0))
2491     return MEMIF_ERR_DISCONNECTED;
2492   uint8_t num =
2493     (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2494     run_args.num_m2s_rings;
2495   if (EXPECT_FALSE (qid >= num))
2496     return MEMIF_ERR_QID;
2497   if (EXPECT_FALSE (!rx))
2498     return MEMIF_ERR_INVAL_ARG;
2499
2500   memif_queue_t *mq = &c->rx_queues[qid];
2501   memif_ring_t *ring = mq->ring;
2502   uint16_t cur_slot, last_slot;
2503   uint16_t ns;
2504   uint16_t mask = (1 << mq->log2_ring_size) - 1;
2505   memif_buffer_t *b0;
2506   *rx = 0;
2507
2508   uint64_t b;
2509   ssize_t r = read (mq->int_fd, &b, sizeof (b));
2510   if (EXPECT_FALSE ((r == -1) && (errno != EAGAIN)))
2511     return memif_syscall_error_handler (errno);
2512
2513   cur_slot = (c->args.is_master) ? mq->last_head : mq->last_tail;
2514   last_slot = (c->args.is_master) ? ring->head : ring->tail;
2515   if (cur_slot == last_slot)
2516     return MEMIF_ERR_SUCCESS;
2517
2518   ns = last_slot - cur_slot;
2519
2520   while (ns && count)
2521     {
2522       b0 = (bufs + *rx);
2523
2524       b0->desc_index = cur_slot;
2525       b0->data = memif_get_buffer (c, ring, cur_slot & mask);
2526       b0->len = ring->desc[cur_slot & mask].length;
2527       /* slave resets buffer length */
2528       if (c->args.is_master == 0)
2529         {
2530           ring->desc[cur_slot & mask].length = c->run_args.buffer_size;
2531         }
2532
2533       b0->flags = MEMIF_BUFFER_FLAG_RX;
2534       if (ring->desc[cur_slot & mask].flags & MEMIF_DESC_FLAG_NEXT)
2535         {
2536           b0->flags |= MEMIF_BUFFER_FLAG_NEXT;
2537           ring->desc[cur_slot & mask].flags &= ~MEMIF_DESC_FLAG_NEXT;
2538         }
2539 /*      b0->offset = ring->desc[cur_slot & mask].offset;*/
2540       b0->ring = ring;
2541 #ifdef MEMIF_DBG_SHM
2542       printf ("data: %p\n", b0->data);
2543       printf ("index: %u\n", b0->desc_index);
2544       printf ("ring: %p\n", b0->ring);
2545       print_bytes (b0->data, b0->len, DBG_RX_BUF);
2546 #endif /* MEMIF_DBG_SHM */
2547       ns--;
2548       *rx += 1;
2549
2550       count--;
2551       cur_slot++;
2552     }
2553
2554   if (c->args.is_master)
2555     mq->last_head = cur_slot;
2556   else
2557     mq->last_tail = cur_slot;
2558
2559   if (ns)
2560     {
2561       DBG ("not enough buffers!");
2562       return MEMIF_ERR_NOBUF;
2563     }
2564
2565   return MEMIF_ERR_SUCCESS;     /* 0 */
2566 }
2567
2568 int
2569 memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
2570                    char *buf, ssize_t buflen)
2571 {
2572   memif_connection_t *c = (memif_connection_t *) conn;
2573   libmemif_main_t *lm;
2574   memif_socket_t *ms;
2575   int err = MEMIF_ERR_SUCCESS, i;
2576   ssize_t l0 = 0, l1;
2577
2578   if (c == NULL)
2579     return MEMIF_ERR_NOCONN;
2580
2581   ms = (memif_socket_t *) c->args.socket;
2582   lm = get_libmemif_main (ms);
2583
2584   l1 = strlen ((char *) c->args.interface_name);
2585   if (l0 + l1 < buflen)
2586     {
2587       md->if_name =
2588         (uint8_t *) strcpy (buf + l0, (char *) c->args.interface_name);
2589       l0 += l1 + 1;
2590     }
2591   else
2592     err = MEMIF_ERR_NOBUF_DET;
2593
2594   l1 = strlen ((char *) lm->app_name);
2595   if (l0 + l1 < buflen)
2596     {
2597       md->inst_name = (uint8_t *) strcpy (buf + l0, (char *) lm->app_name);
2598       l0 += l1 + 1;
2599     }
2600   else
2601     err = MEMIF_ERR_NOBUF_DET;
2602
2603   l1 = strlen ((char *) c->remote_if_name);
2604   if (l0 + l1 < buflen)
2605     {
2606       md->remote_if_name =
2607         (uint8_t *) strcpy (buf + l0, (char *) c->remote_if_name);
2608       l0 += l1 + 1;
2609     }
2610   else
2611     err = MEMIF_ERR_NOBUF_DET;
2612
2613   l1 = strlen ((char *) c->remote_name);
2614   if (l0 + l1 < buflen)
2615     {
2616       md->remote_inst_name =
2617         (uint8_t *) strcpy (buf + l0, (char *) c->remote_name);
2618       l0 += l1 + 1;
2619     }
2620   else
2621     err = MEMIF_ERR_NOBUF_DET;
2622
2623   md->id = c->args.interface_id;
2624
2625   if (strlen ((char *) c->args.secret) > 0)
2626     {
2627       l1 = strlen ((char *) c->args.secret);
2628       if (l0 + l1 < buflen)
2629         {
2630           md->secret = (uint8_t *) strcpy (buf + l0, (char *) c->args.secret);
2631           l0 += l1 + 1;
2632         }
2633       else
2634         err = MEMIF_ERR_NOBUF_DET;
2635     }
2636
2637   md->role = (c->args.is_master) ? 0 : 1;
2638   md->mode = c->args.mode;
2639
2640   l1 = strlen ((char *) ms->filename);
2641   if (l0 + l1 < buflen)
2642     {
2643       md->socket_filename =
2644         (uint8_t *) strcpy (buf + l0, (char *) ms->filename);
2645       l0 += l1 + 1;
2646     }
2647   else
2648     err = MEMIF_ERR_NOBUF_DET;
2649
2650   l1 = strlen ((char *) c->remote_disconnect_string);
2651   if (l0 + l1 < buflen)
2652     {
2653       md->error =
2654         (uint8_t *) strcpy (buf + l0, (char *) c->remote_disconnect_string);
2655       l0 += l1 + 1;
2656     }
2657   else
2658     err = MEMIF_ERR_NOBUF_DET;
2659
2660   md->regions_num = c->regions_num;
2661   l1 = sizeof (memif_region_details_t) * md->regions_num;
2662   if (l0 + l1 <= buflen)
2663     {
2664       md->regions = (memif_region_details_t *) (buf + l0);
2665       for (i = 0; i < md->regions_num; i++)
2666         {
2667           md->regions[i].index = i;
2668           md->regions[i].addr = c->regions[i].addr;
2669           md->regions[i].size = c->regions[i].region_size;
2670           md->regions[i].fd = c->regions[i].fd;
2671           md->regions[i].is_external = c->regions[i].is_external;
2672         }
2673       l0 += l1;
2674     }
2675   else
2676     err = MEMIF_ERR_NOBUF_DET;
2677
2678   md->rx_queues_num =
2679     (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2680     run_args.num_m2s_rings;
2681
2682   l1 = sizeof (memif_queue_details_t) * md->rx_queues_num;
2683   if (l0 + l1 <= buflen)
2684     {
2685       md->rx_queues = (memif_queue_details_t *) (buf + l0);
2686       for (i = 0; i < md->rx_queues_num; i++)
2687         {
2688           md->rx_queues[i].region = c->rx_queues[i].region;
2689           md->rx_queues[i].qid = i;
2690           md->rx_queues[i].ring_size = (1 << c->rx_queues[i].log2_ring_size);
2691           md->rx_queues[i].flags = c->rx_queues[i].ring->flags;
2692           md->rx_queues[i].head = c->rx_queues[i].ring->head;
2693           md->rx_queues[i].tail = c->rx_queues[i].ring->tail;
2694           md->rx_queues[i].buffer_size = c->run_args.buffer_size;
2695         }
2696       l0 += l1;
2697     }
2698   else
2699     err = MEMIF_ERR_NOBUF_DET;
2700
2701   md->tx_queues_num =
2702     (c->args.is_master) ? c->run_args.num_m2s_rings : c->
2703     run_args.num_s2m_rings;
2704
2705   l1 = sizeof (memif_queue_details_t) * md->tx_queues_num;
2706   if (l0 + l1 <= buflen)
2707     {
2708       md->tx_queues = (memif_queue_details_t *) (buf + l0);
2709       for (i = 0; i < md->tx_queues_num; i++)
2710         {
2711           md->tx_queues[i].region = c->tx_queues[i].region;
2712           md->tx_queues[i].qid = i;
2713           md->tx_queues[i].ring_size = (1 << c->tx_queues[i].log2_ring_size);
2714           md->tx_queues[i].flags = c->tx_queues[i].ring->flags;
2715           md->tx_queues[i].head = c->tx_queues[i].ring->head;
2716           md->tx_queues[i].tail = c->tx_queues[i].ring->tail;
2717           md->tx_queues[i].buffer_size = c->run_args.buffer_size;
2718         }
2719       l0 += l1;
2720     }
2721   else
2722     err = MEMIF_ERR_NOBUF_DET;
2723
2724   md->link_up_down = (c->fd > 0) ? 1 : 0;
2725
2726   return err;                   /* 0 */
2727 }
2728
2729 int
2730 memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *efd)
2731 {
2732   memif_connection_t *c = (memif_connection_t *) conn;
2733   uint8_t num;
2734
2735   *efd = -1;
2736   if (c == NULL)
2737     return MEMIF_ERR_NOCONN;
2738   if (c->fd < 0)
2739     return MEMIF_ERR_DISCONNECTED;
2740
2741   num =
2742     (c->args.is_master) ? c->run_args.num_s2m_rings : c->
2743     run_args.num_m2s_rings;
2744   if (qid >= num)
2745     return MEMIF_ERR_QID;
2746
2747   *efd = c->rx_queues[qid].int_fd;
2748
2749   return MEMIF_ERR_SUCCESS;
2750 }
2751
2752 int
2753 memif_cleanup ()
2754 {
2755   libmemif_main_t *lm = &libmemif_main;
2756   int err;
2757
2758   err = memif_delete_socket ((memif_socket_handle_t *) & lm->default_socket);
2759   if (err != MEMIF_ERR_SUCCESS)
2760     return err;
2761
2762   if (lm->control_list)
2763     lm->free (lm->control_list);
2764   lm->control_list = NULL;
2765   if (lm->interrupt_list)
2766     lm->free (lm->interrupt_list);
2767   lm->interrupt_list = NULL;
2768   if (lm->socket_list)
2769     lm->free (lm->socket_list);
2770   lm->socket_list = NULL;
2771   if (lm->pending_list)
2772     lm->free (lm->pending_list);
2773   lm->pending_list = NULL;
2774   if (lm->poll_cancel_fd != -1)
2775     close (lm->poll_cancel_fd);
2776
2777   return MEMIF_ERR_SUCCESS;     /* 0 */
2778 }
2779
2780 int
2781 memif_per_thread_cleanup (memif_per_thread_main_handle_t * pt_main)
2782 {
2783   libmemif_main_t *lm = (libmemif_main_t *) * pt_main;
2784
2785   if (lm == NULL)
2786     return MEMIF_ERR_INVAL_ARG;
2787
2788   /* No default socket in case of per thread */
2789
2790   if (lm->control_list)
2791     lm->free (lm->control_list);
2792   lm->control_list = NULL;
2793   if (lm->interrupt_list)
2794     lm->free (lm->interrupt_list);
2795   lm->interrupt_list = NULL;
2796   if (lm->socket_list)
2797     lm->free (lm->socket_list);
2798   lm->socket_list = NULL;
2799   if (lm->pending_list)
2800     lm->free (lm->pending_list);
2801   lm->pending_list = NULL;
2802   if (lm->poll_cancel_fd != -1)
2803     close (lm->poll_cancel_fd);
2804
2805   lm->free (lm);
2806
2807   *pt_main = NULL;
2808
2809   return MEMIF_ERR_SUCCESS;     /* 0 */
2810 }