OSDN Git Service

Update INSTALL.ja.utf-8 for new release.
[ultramonkey-l7/ultramonkey-l7-v2.git] / src / iomux.c
1 /*!
2  * @file        iomux.c
3  * @brief       It is a code in which sets of iomux are managed. 
4  * @brief       An actual set is operated only by this code. 
5  * @brief       Moreover, epoll is operated by this code. 
6  * @brief       L7VSD: Linux Virtual Server for Layer7 Load Balancing
7  *
8  * Copyright (C) 2005  NTT COMWARE Corporation.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301 USA
24  *
25  **********************************************************************/
26
27 #include <sys/types.h>
28 #include <sys/time.h>
29 #include <sys/epoll.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <assert.h>
33 #include <time.h>
34 #include <sys/time.h>
35 #include <glib.h>
36 #include "parameter_wrapper.h"
37 #include "logger_wrapper.h"
38 #include "l7vs.h"
39 #include "l7vs_conn.h"
40 #include "l7vs_iomuxlist.h"
41
42 /*
43 #ifndef  MAXEVENTS
44 #define  MAXEVENTS      1024            //! epoll max event size
45 #endif
46 */
47 static int maxevents = 1024;
48 static struct l7vs_iomux*       iomux_array = NULL;             //! iomux array
49 static struct epoll_event*      event_array = NULL;             //! event list
50
51 static GHashTable*              iomux_hash = NULL;                      //! fd hashtable
52 static GList*                   iomux_avail_list = NULL;        //! iomux available list
53 static unsigned int             iomux_avail_list_length;        //! number of iomux available list
54 static int                      eventpoll = -1;                                 //! epoll fd
55
56 //inner functions
57 static gboolean removeall( gpointer, gpointer, gpointer );
58
59 /*!
60  * initialize iomux_hash
61  *
62  * @param[in]   void
63  * @return      status
64  * @retval      0       failed
65  * @retval      1       succeed
66  */
67 int
68 l7vs_iomux_init()
69 {
70         /*-------- DEBUG LOG --------*/
71         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
72                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,1,
73                         "in_function: int l7vs_iomux_init() ");
74         }
75         /*------ DEBUG LOG END ------*/
76
77         int ret = parameter_is_int_exist( PARAM_COMP_IOMUX, "max_events" );
78     if (ret) {
79         int event =  parameter_get_int_value( PARAM_COMP_IOMUX, "max_events" );
80         if (event > 0)
81             maxevents = event;
82         else {
83                 LOGGER_PUT_LOG_WARN(LOG_CAT_L7VSD_EVENT,1,
84                         "l7vsd uses default max_events = %d ,because your value is invalid ",maxevents);
85         }
86     }
87     else {
88                 LOGGER_PUT_LOG_WARN(LOG_CAT_L7VSD_EVENT,2,
89                         "max_events is not specified. l7vsd uses default max_events = %d ",maxevents);
90     }
91
92         iomux_avail_list_length = maxevents;
93         if (iomux_avail_list == NULL) {
94             iomux_array = (struct l7vs_iomux*) calloc(sizeof(struct l7vs_iomux), maxevents);
95         }
96         if (!iomux_array) {     
97                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,26, "error / calloc failed");
98                 /*-------- DEBUG LOG --------*/
99                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
100                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,59,
101                                 "in_function: int l7vs_iomux_init() "
102                                 "return_value: -1");
103                 }
104                 /*------ DEBUG LOG END ------*/
105                 return -1;
106         }
107
108         if (iomux_avail_list == NULL) {
109                 event_array = (struct epoll_event*) calloc(sizeof(struct epoll_event), maxevents);
110         }
111         if (!event_array) {     
112                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,27, "error / calloc failed");
113                 /*-------- DEBUG LOG --------*/
114                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
115                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,60,
116                                 "in_function: int l7vs_iomux_init() "
117                                 "return_value: -1");
118                 }
119                 /*------ DEBUG LOG END ------*/
120                 return -1;
121         }
122
123         int i = 0;
124         struct l7vs_iomux temp_iom = {-1, NULL, iomux_create, NULL};
125
126         if (-1 !=  eventpoll) {
127                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,4, "error / epoll already exist");
128                 /*-------- DEBUG LOG --------*/
129                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
130                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,2,
131                                 "in_function: int l7vs_iomux_init() "
132                                 "return_value: -1");
133                 }
134                 /*------ DEBUG LOG END ------*/
135                 return -1;
136         }
137
138         //create epoll
139         /*-------- DEBUG LOG --------*/
140         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
141                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,3,
142                         "epoll_create : size=%d",
143                         maxevents);
144         }
145         /*------ DEBUG LOG END ------*/
146         eventpoll = epoll_create(maxevents);
147         if (0 > eventpoll) {
148                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,5, "error / epoll create error");
149                 /*-------- DEBUG LOG --------*/
150                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
151                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,4,
152                                 "in_function: int l7vs_iomux_init() "
153                                 "return_value: %d", eventpoll);
154                 }
155                 /*------ DEBUG LOG END ------*/
156                 return eventpoll;
157         }
158
159         //new hashtable
160         if (!iomux_hash) {
161                 iomux_hash = g_hash_table_new(&g_int_hash, &g_int_equal);
162         }
163
164         //init iomux_array and avail_list
165         if (!iomux_avail_list) {
166                 for (i = 0; i < maxevents; ++i) {
167                         memcpy(iomux_array + i, &temp_iom, sizeof(struct l7vs_iomux));
168                         iomux_avail_list = g_list_append(iomux_avail_list, &iomux_array[i]);
169                 }
170         }
171
172         /*-------- DEBUG LOG --------*/
173         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
174                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,5,
175                         "in_function: int l7vs_iomux_init() "
176                         "return_value: 1");
177         }
178         /*------ DEBUG LOG END ------*/
179         return 1;
180 }
181
182 /*!
183  * finalize iomux_hash
184  *
185  * @param[in]   void
186  * @return      void
187  */
188 void
189 l7vs_iomux_fini()
190 {
191         /*-------- DEBUG LOG --------*/
192         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
193                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,6,
194                         "in_function: void l7vs_iomux_fini() ");
195         }
196         /*------ DEBUG LOG END ------*/
197
198         if (-1 == eventpoll) {
199                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,6, "error / epoll is not initialized");
200                 /*-------- DEBUG LOG --------*/
201                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
202                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,7,
203                                 "out_function: void l7vs_iomux_fini() "
204                                 "return_value: void");
205                 }
206                 /*------ DEBUG LOG END ------*/
207                 return;
208         }
209
210         //all fd close and remove
211         l7vs_iomux_removeall();
212
213         //g_hashtable destroy
214         if (iomux_hash) {
215                 g_hash_table_destroy(iomux_hash);
216                 iomux_hash = NULL;
217         }
218
219         //g_list free
220         if (iomux_avail_list) {
221                 g_list_free(iomux_avail_list);
222                 iomux_avail_list = NULL;
223         }
224
225         //epoll close
226         /*-------- DEBUG LOG --------*/
227         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
228                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,8,
229                         "close: eventpoll=%d",
230                         eventpoll);
231         }
232         /*------ DEBUG LOG END ------*/
233         close(eventpoll);
234         eventpoll = -1;
235         
236         if (iomux_array) {
237                 free(iomux_array);
238                 iomux_array = NULL;
239         }
240         
241         if (event_array) {
242                 free(event_array);
243                 event_array = NULL;
244         }
245         
246         /*-------- DEBUG LOG --------*/
247         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
248                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,9,
249                         "out_function: void l7vs_iomux_fini() "
250                         "return_value: void");
251         }
252         /*------ DEBUG LOG END ------*/
253 }
254
255 /*!
256  * get available iom from avail_list
257  *
258  * @param[in]   void
259  * @return      available iom
260  */
261 struct l7vs_iomux*
262 l7vs_iomux_get_from_avail_list()
263 {
264         /*-------- DEBUG LOG --------*/
265         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
266                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,10,
267                         "in_function: struct l7vs_iomux* l7vs_iomux_get_from_avail_list() ");
268         }
269         /*------ DEBUG LOG END ------*/
270
271         if (0 == iomux_avail_list_length) {
272                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,7, "warning / no iomux available");
273                 /*-------- DEBUG LOG --------*/
274                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
275                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,11,
276                                 "out_function: struct l7vs_iomux* l7vs_iomux_get_from_avail_list() "
277                                 "return_value: iom=NULL");
278                 }
279                 /*------ DEBUG LOG END ------*/
280                 return NULL;
281         }
282
283         struct l7vs_iomux *iom = (struct l7vs_iomux *)(g_list_first(iomux_avail_list))->data;
284         iomux_avail_list = g_list_remove(iomux_avail_list, (gpointer)iom);
285         --iomux_avail_list_length;
286         /*-------- DEBUG LOG --------*/
287         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
288                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,12,
289                         "iomux_avail_list_length: %d",
290                         iomux_avail_list_length);
291         }
292         /*------ DEBUG LOG END ------*/
293
294         /*-------- DEBUG LOG --------*/
295         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
296                 char ret_iomux_str[DEBUG_STR_LEN] = {0};
297                 l7vs_iomux_c_str(ret_iomux_str, iom);
298                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,13,
299                         "out_function: struct l7vs_iomux* l7vs_iomux_get_from_avail_list() "
300                         "return_value: iom=%s",
301                         ret_iomux_str);
302         }
303         /*------ DEBUG LOG END ------*/
304         return iom;
305 }
306
307 /*!
308  * put disuse iom to avail_list
309  *
310  * @param[in]   iom     return iom
311  * @return      void
312  */
313 void
314 l7vs_iomux_put_to_avail_list(struct l7vs_iomux *iom)
315 {
316         /*-------- DEBUG LOG --------*/
317         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
318                 char iomux_str[DEBUG_STR_LEN] = {0};
319                 l7vs_iomux_c_str(iomux_str, iom);
320                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,14,
321                         "in_function: void l7vs_iomux_put_to_avail_list(struct l7vs_iomux *iom) "
322                         "iom=%s",
323                         iomux_str);
324         }
325         /*------ DEBUG LOG END ------*/
326
327         if (!iom) {
328                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,8, "error / iom is null");
329                 /*-------- DEBUG LOG --------*/
330                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
331                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,15,
332                                 "out_function: void l7vs_iomux_put_to_avail_list(struct l7vs_iomux *iom) "
333                                 "return_value: void");
334                 }
335                 /*------ DEBUG LOG END ------*/
336                 return;
337         }
338
339         iom->fd = -1;
340         iom->callback = NULL;
341         iom->status = iomux_create;
342         iom->data = NULL;
343
344         iomux_avail_list = g_list_append(iomux_avail_list, (gpointer)iom);
345         ++iomux_avail_list_length;
346         /*-------- DEBUG LOG --------*/
347         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
348                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,16,
349                         "iomux_avail_list_length: %d",
350                         iomux_avail_list_length);
351         }
352         /*------ DEBUG LOG END ------*/
353
354         /*-------- DEBUG LOG --------*/
355         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
356                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,17,
357                         "out_function: void l7vs_iomux_put_to_avail_list(struct l7vs_iomux *iom) "
358                         "return_value: void");
359         }
360         /*------ DEBUG LOG END ------*/
361 }
362
363 /*!
364  * iomux is added to hashtbale
365  *
366  * @param[in]   *iom    iompointer
367  * @param[in]   action  iom epoll action
368  * @return      void
369  */
370 void 
371 l7vs_iomux_add(struct l7vs_iomux* iom, enum iomaction action)
372 {
373         /*-------- DEBUG LOG --------*/
374         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
375                 char iomux_str[DEBUG_STR_LEN] = {0};
376                 l7vs_iomux_c_str(iomux_str, iom);
377                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,18,
378                         "in_function: void l7vs_iomux_add(struct l7vs_iomux* iom, enum iomaction action) "
379                         "iom=%s: "
380                         "iomaction=%d",
381                         iomux_str, action);
382         }
383         /*------ DEBUG LOG END ------*/
384
385         int ret = 0;
386         struct epoll_event event;
387
388         if (!iom) {
389                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,9, "error / iom is null");
390                 /*-------- DEBUG LOG --------*/
391                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
392                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,19,
393                                 "out_function: void l7vs_iomux_add(struct l7vs_iomux* iom, enum iomaction action) "
394                                 "return_value: void");
395                 }
396                 /*------ DEBUG LOG END ------*/
397                 return;
398         }
399         if (-1 == iom->fd) {
400                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,10, "error / fd is not specified");
401                 /*-------- DEBUG LOG --------*/
402                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
403                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,20,
404                                 "out_function: void l7vs_iomux_add(struct l7vs_iomux* iom, enum iomaction action) "
405                                 "return_value: void");
406                 }
407                 /*------ DEBUG LOG END ------*/
408                 return;
409         }
410
411         event.data.ptr = iom;
412         switch( action ){
413                 case iom_read:
414                         event.events = EPOLLET | EPOLLIN | EPOLLHUP;
415                         break;
416                 case iom_write:
417                         event.events = EPOLLET | EPOLLOUT | EPOLLHUP;
418                         break;
419                 default:
420                         //error !
421                         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,11, "error / invalid action");
422                         /*-------- DEBUG LOG --------*/
423                         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
424                                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,21,
425                                         "out_function: void l7vs_iomux_add(struct l7vs_iomux* iom, enum iomaction action) "
426                                         "return_value: void");
427                         }
428                         /*------ DEBUG LOG END ------*/
429                         return;
430         }
431
432         /*-------- DEBUG LOG --------*/
433         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
434                 char iomux_str[DEBUG_STR_LEN] = {0};
435                 l7vs_iomux_c_str(iomux_str, iom);       
436                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,22,
437                         "epoll_ctl : epfd=%d: op=EPOLL_CTL_ADD: fd=%d: event.events=%d: event.data=%s",
438                         eventpoll, iom->fd, event.events, iomux_str);
439         }
440         /*------ DEBUG LOG END ------*/
441         ret = epoll_ctl( eventpoll, EPOLL_CTL_ADD, iom->fd, &event );
442         g_hash_table_insert(iomux_hash, &(iom->fd), iom );
443
444         /*-------- DEBUG LOG --------*/
445         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
446                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,23,
447                         "out_function: void l7vs_iomux_add(struct l7vs_iomux* iom, enum iomaction action) "
448                         "return_value: void");
449         }
450         /*------ DEBUG LOG END ------*/
451 }
452
453 /*!
454  * iomux is remove from hashtable
455  *
456  * @param[in]   *iom    iompointer
457  * @return      void
458  */
459 void
460 l7vs_iomux_remove(struct l7vs_iomux* iom)
461 {
462         /*-------- DEBUG LOG --------*/
463         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
464                 char iomux_str[DEBUG_STR_LEN] = {0};
465                 l7vs_iomux_c_str(iomux_str, iom);
466                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,24,
467                         "in_function: void l7vs_iomux_remove(struct l7vs_iomux* iom) "
468                         "iom=%s",
469                         iomux_str);
470         }
471         /*------ DEBUG LOG END ------*/
472
473         int ret = 0;
474
475         if (!iom) {
476                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,12, "error / iom is null");
477                 /*-------- DEBUG LOG --------*/
478                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
479                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,25,
480                                 "out_function: void l7vs_iomux_remove(struct l7vs_iomux* iom) "
481                                 "return_value: void");
482                 }
483                 /*------ DEBUG LOG END ------*/
484                 return;
485         }
486         if (-1 == iom->fd) {
487                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,13, "error / fd is not specified");
488                 /*-------- DEBUG LOG --------*/
489                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
490                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,26,
491                                 "out_function: void l7vs_iomux_remove(struct l7vs_iomux* iom) "
492                                 "return_value: void");
493                 }
494                 /*------ DEBUG LOG END ------*/
495                 return;
496         }
497         
498         /*-------- DEBUG LOG --------*/
499         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
500                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,27,
501                         "epoll_ctl : epfd=%d: op=EPOLL_CTL_DEL: fd=%d",
502                         eventpoll, iom->fd);
503         }
504         /*------ DEBUG LOG END ------*/
505         ret = epoll_ctl(eventpoll, EPOLL_CTL_DEL, iom->fd, NULL);
506         g_hash_table_remove(iomux_hash, &(iom->fd));
507
508         /*-------- DEBUG LOG --------*/
509         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
510                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,28,
511                         "out_function: void l7vs_iomux_remove(struct l7vs_iomux* iom) "
512                         "return_value: void");
513         }
514         /*------ DEBUG LOG END ------*/
515 }
516
517 /*!
518  * iomux modify epoll events
519  *
520  * @param[in]   *iom    iom pointer
521  * @param[in]   action  iom action mode
522  * @return      void
523  */
524 void
525 l7vs_iomux_mod(struct l7vs_iomux* iom, enum iomaction action)
526 {
527         /*-------- DEBUG LOG --------*/
528         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
529                 char iomux_str[DEBUG_STR_LEN] = {0};
530                 l7vs_iomux_c_str(iomux_str, iom);
531                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,29,
532                         "in_function: void l7vs_iomux_mod(struct l7vs_iomux* iom, enum iomaction action) "
533                         "iom=%s: "
534                         "iomaction=%d",
535                         iomux_str, action);
536         }
537         /*------ DEBUG LOG END ------*/
538
539         int ret = 0;
540         struct epoll_event      event;
541
542         if (!iom) {
543                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,14, "error / iom is null");
544                 /*-------- DEBUG LOG --------*/
545                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
546                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,30,
547                                 "out_function: void l7vs_iomux_mod(struct l7vs_iomux* iom, enum iomaction action) "
548                                 "return_value: void");
549                 }
550                 /*------ DEBUG LOG END ------*/
551                 return;
552         }
553         if (-1 == iom->fd) {
554                 LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,15, "error / fd is not specified");
555                 /*-------- DEBUG LOG --------*/
556                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
557                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,31,
558                                 "out_function: void l7vs_iomux_mod(struct l7vs_iomux* iom, enum iomaction action) "
559                                 "return_value: void");
560                 }
561                 /*------ DEBUG LOG END ------*/
562                 return;
563         }
564
565         event.data.ptr = iom;
566         switch (action) {
567                 case    iom_read:
568                         event.events = EPOLLET | EPOLLIN | EPOLLHUP;
569                         break;
570                 case    iom_write:
571                         event.events = EPOLLET | EPOLLOUT | EPOLLHUP;
572                         break;
573                 case    iom_hup:
574                         event.events = EPOLLET | EPOLLHUP;
575                         break;
576                 default:
577                         //error !
578                         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,16, "error / invalid action");
579                         /*-------- DEBUG LOG --------*/
580                         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
581                                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,32,
582                                         "out_function: void l7vs_iomux_mod(struct l7vs_iomux* iom, enum iomaction action) "
583                                         "return_value: void");
584                         }
585                         /*------ DEBUG LOG END ------*/
586                         return;
587         }
588         /*-------- DEBUG LOG --------*/
589         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
590                 char iomux_str[DEBUG_STR_LEN] = {0};
591                 l7vs_iomux_c_str(iomux_str, iom);       
592                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,33,
593                         "epoll_ctl : epfd=%d: op=EPOLL_CTL_MOD: fd=%d: event.events=%d: event.data=%s",
594                         eventpoll, iom->fd, event.events, iomux_str);
595         }
596         /*------ DEBUG LOG END ------*/
597         ret = epoll_ctl(eventpoll, EPOLL_CTL_MOD, iom->fd, &event);
598
599         /*-------- DEBUG LOG --------*/
600         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
601                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,34,
602                         "out_function: void l7vs_iomux_mod(struct l7vs_iomux* iom, enum iomaction action) "
603                         "return_value: void");
604         }
605         /*------ DEBUG LOG END ------*/
606 }
607
608 /*!
609  * close all filedescriptor
610  *
611  * removeall() function is called l7vs_iomux_delall()
612  * GHashTable is don't all contenior;
613  * but function callback set all contenor;
614  */
615 static gboolean
616 removeall(gpointer key, gpointer value, gpointer userdata)
617 {
618         /*-------- DEBUG LOG --------*/
619         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
620                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,35,
621                         "in_function: static gboolean removeall(gpointer key, gpointer value, gpointer userdata) "
622                         "key=%p: "
623                         "value=%p: "
624                         "userdata=%p",
625                         key, value, userdata);
626         }
627         /*------ DEBUG LOG END ------*/
628
629         struct l7vs_iomux *iom = (struct l7vs_iomux *)value;
630         /*-------- DEBUG LOG --------*/
631         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
632                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,36,
633                         "epoll_ctl : epfd=%d: op=EPOLL_CTL_DEL: fd=%d",
634                         eventpoll, iom->fd);
635         }
636         /*------ DEBUG LOG END ------*/
637         epoll_ctl(eventpoll, EPOLL_CTL_DEL, iom->fd, NULL);
638         /*-------- DEBUG LOG --------*/
639         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
640                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,37,
641                         "out_function: static gboolean removeall(gpointer key, gpointer value, gpointer userdata) "
642                         "return_value: TRUE");
643         }
644         /*------ DEBUG LOG END ------*/
645         return TRUE;
646 }
647
648 /*!
649  * all contnior delete hash_table
650  *
651  * @return      void*
652  */ 
653 void
654 l7vs_iomux_removeall()
655 {
656         /*-------- DEBUG LOG --------*/
657         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
658                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,38,
659                         "in_function: void l7vs_iomux_removeall()");
660         }
661         /*------ DEBUG LOG END ------*/
662         g_hash_table_foreach_remove(iomux_hash, removeall, NULL);
663         /*-------- DEBUG LOG --------*/
664         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
665                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,39,
666                         "out_function: void l7vs_iomux_removeall() "
667                         "return_value: TRUE");
668         }
669         /*------ DEBUG LOG END ------*/
670 }
671
672 /*!
673  * polling function for epoll.
674  *
675  * @param[in]   *timo   waittime;
676  * @return      error   
677  */
678 int
679 l7vs_iomux_poll(struct timeval *timo, int blocking)
680 {
681         /*-------- DEBUG LOG --------*/
682         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
683                 if (!timo) {
684                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,40,
685                                 "in_function: int l7vs_iomux_poll(struct timeval *timo, int blocking) "
686                                 "timo=NULL, blocking = %d", blocking);
687                 }
688                 else {
689                         char time_str[DEBUG_STR_LEN] = {0};
690                         snprintf(time_str, DEBUG_STR_LEN,
691                                 "timeval="
692                                 "{tv_sec=%ld: "
693                                 "tv_usec=%ld}"
694                                 , timo->tv_sec
695                                 , timo->tv_usec);
696                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,41,
697                                 "in_function: int l7vs_iomux_poll(struct timeval *timo) "
698                                 "timo=%s, blocking=%d",
699                                 time_str, blocking);
700                 }
701         }
702         /*------ DEBUG LOG END ------*/
703
704         int     fdnum;
705         int     i;
706         int     ret;
707         struct l7vs_iomux       *iom;
708         struct l7vs_conn        *conn;
709
710         /*-------- DEBUG LOG --------*/
711         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
712                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,42,
713                         "epoll_wait param: epfd=%d: maxevents=%d: timeout=0",
714                         eventpoll, maxevents);
715         }
716         /*------ DEBUG LOG END ------*/
717         fdnum = epoll_wait(eventpoll, event_array, maxevents, blocking);
718         /*-------- DEBUG LOG --------*/
719         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
720                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,43,
721                         "epoll_wait result: fdnum=%d",
722                         fdnum);
723         }
724         /*------ DEBUG LOG END ------*/
725         for (i = 0; i < fdnum; ++i) {
726                 if (event_array[i].data.ptr) {
727                         iom = (struct l7vs_iomux *)event_array[i].data.ptr;
728                         /*-------- DEBUG LOG --------*/
729                         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
730                                 char iomux_str[DEBUG_STR_LEN] = {0};
731                                 l7vs_iomux_c_str(iomux_str, iom);
732                                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,44,
733                                         "event_array[%d].data.ptr: %s",
734                                         i, iomux_str);
735                         }
736                         /*------ DEBUG LOG END ------*/
737                         if (iom->status != iomux_create) {
738                                 if (event_array[i].events & (EPOLLHUP | EPOLLERR)) {
739                                         // disconnect when sending
740                                         conn = (struct l7vs_conn *)iom->data;
741                                         /*-------- DEBUG LOG --------*/
742                                         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
743                                                 char conn_str[DEBUG_STR_LEN] = {0};
744                                                 l7vs_conn_c_str(conn_str, conn);
745                                                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,45,
746                                                         "pointer_assign: conn=%s",
747                                                         conn_str);
748                                         }
749                                         /*------ DEBUG LOG END ------*/
750
751                                         // destroy conn
752                                         l7vs_conn_destroy(conn);
753
754                                 } else if (event_array[i].events & (EPOLLIN | EPOLLOUT)) {
755                                         if (iom->status != iomux_disabled) {
756                                                 if (iom->callback) {
757                                                         // if there is mismatch between status and events,
758                                                         // read event will regist after, (when send was finished) 
759                                                         // therefore, through callback
760                                                         if (!(event_array[i].events & EPOLLIN &&
761                                                               (iomux_conn_sending == iom->status ||
762                                                                iomux_conn_sending_busy == iom->status))) {
763                                                                 // execute callback
764                                                                 /*-------- DEBUG LOG --------*/
765                                                                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
766                                                                         char ex_iomux_str[DEBUG_STR_LEN] = {0};
767                                                                         l7vs_iomux_c_str(ex_iomux_str, iom);
768                                                                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,46,
769                                                                                 "iom->callback: %p: iom=%s",
770                                                                                 iom->callback, ex_iomux_str);
771                                                                 }
772                                                                 /*------ DEBUG LOG END ------*/
773                                                                 ret = iom->callback(iom);
774                                                                 /*-------- DEBUG LOG --------*/
775                                                                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
776                                                                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,47,
777                                                                                 "iom->callback result: ret=%d",
778                                                                                 ret);
779                                                                 }
780                                                                 /*------ DEBUG LOG END ------*/
781         
782                                                         }
783                                                 } else {
784                                                         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,17, "error / callback not bind");
785                                                 }
786                                         }
787                                 } else {
788                                         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,18, "error / unkown event:%x", event_array[i].events);
789                                 }
790                         } else {
791                                 if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
792                                         LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,48, "debug / invalid status:iomux_create");
793                                 }
794                         }
795                 } else {
796                         LOGGER_PUT_LOG_ERROR(LOG_CAT_L7VSD_EVENT,19, "error / epolldata.data.ptr is null");
797                 }
798         }
799
800         /*-------- DEBUG LOG --------*/
801         if (LOG_LV_DEBUG == logger_get_log_level(LOG_CAT_L7VSD_EVENT)) {
802                 LOGGER_PUT_LOG_DEBUG(LOG_CAT_L7VSD_EVENT,49,
803                         "out_function: int l7vs_iomux_poll(struct timeval *timo) "
804                         "return_value: 1");
805         }
806         /*------ DEBUG LOG END ------*/
807         return 1;
808
809 }