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