1414#include <fcntl.h>
1515#include <errno.h>
1616#include <limits.h> // PIPE_BUF
17+ #include <sys/timerfd.h>
18+ #include <poll.h>
1719
1820#include <ipfixcol2.h>
1921
2022#include "cpipe.h"
2123#include "../verbose.h"
2224
25+ /// Periodic message delay in milliseconds
26+ #define IPX_PERIODIC_MESSAGE_DELAY 100
2327/// Invalid file descriptor value
2428#define INVALID_FD (-1)
2529/// Configuration pipe - cpipe_fd[0] for read, cpipe_fd[1] for write
2630static int cpipe_fd [2 ] = {INVALID_FD , INVALID_FD };
31+ /// Periodic timer file descriptor
32+ static int periodic_timer_fd = INVALID_FD ;
2733/// Identification of the module (just for log!)
2834static const char * module = "Configuration pipe" ;
2935
@@ -61,6 +67,21 @@ ipx_cpipe_init()
6167 return IPX_ERR_DENIED ;
6268 }
6369
70+ periodic_timer_fd = timerfd_create (CLOCK_MONOTONIC , 0 );
71+ if (periodic_timer_fd == -1 ) {
72+ ipx_strerror (errno , err_str );
73+ IPX_ERROR (module , "timerfd_create() failed: %s" , err_str );
74+ ipx_cpipe_destroy ();
75+ return IPX_ERR_DENIED ;
76+ }
77+ struct itimerspec timer_settings ;
78+ struct timespec interval ;
79+ interval .tv_nsec = (IPX_PERIODIC_MESSAGE_DELAY % 1000 ) * 1000000 ;
80+ interval .tv_sec = IPX_PERIODIC_MESSAGE_DELAY / 1000 ;
81+ timer_settings .it_interval = interval ;
82+ timer_settings .it_value = interval ;
83+ timerfd_settime (periodic_timer_fd , 0 , & timer_settings , NULL );
84+
6485 return IPX_OK ;
6586}
6687
@@ -75,16 +96,31 @@ ipx_cpipe_destroy()
7596 close (cpipe_fd [i ]);
7697 cpipe_fd [i ] = INVALID_FD ;
7798 }
99+ if (periodic_timer_fd != INVALID_FD ) {
100+ close (periodic_timer_fd );
101+ periodic_timer_fd = INVALID_FD ;
102+ }
78103}
79104
80105int
81106ipx_cpipe_receive (struct ipx_cpipe_req * msg )
82107{
83108 const size_t buffer_size = sizeof (* msg );
84109 size_t buffer_read = 0 ;
110+ uint64_t periodic_timer_buf ;
111+
112+ struct pollfd fds ;
113+ fds .fd = periodic_timer_fd ;
114+ fds .events = POLLIN ;
85115
86116 errno = 0 ;
87117 while (buffer_read < buffer_size ) {
118+ if (poll (& fds , 1 , 0 ) != -1 ) {
119+ // Reset timer expiration counter
120+ if (read (periodic_timer_fd , & periodic_timer_buf , sizeof (periodic_timer_buf )) != -1 ) {
121+ ipx_cpipe_send (NULL , IPX_CPIPE_TYPE_PERIODIC );
122+ }
123+ }
88124 uint8_t * ptr = ((uint8_t * ) msg ) + buffer_read ;
89125 ssize_t rc = read (cpipe_fd [0 ], ptr , buffer_size - buffer_read );
90126 if (rc > 0 ) {
@@ -113,16 +149,15 @@ ipx_cpipe_receive(struct ipx_cpipe_req *msg)
113149}
114150
115151int
116- ipx_cpipe_send_term (ipx_ctx_t * ctx , enum ipx_cpipe_type type )
152+ ipx_cpipe_send (ipx_ctx_t * ctx , enum ipx_cpipe_type type )
117153{
118154 // WARNING: Keep on mind that this function can be called from signal handler!
119155
120156 // In case we change 'errno' (e.g. write())
121157 int errno_backup = errno ;
122158
123- if (type != IPX_CPIPE_TYPE_TERM_SLOW
124- && type != IPX_CPIPE_TYPE_TERM_FAST
125- && type != IPX_CPIPE_TYPE_TERM_DONE ) {
159+ if (type != IPX_CPIPE_TYPE_TERM_SLOW && type != IPX_CPIPE_TYPE_TERM_FAST
160+ && type != IPX_CPIPE_TYPE_TERM_DONE && type != IPX_CPIPE_TYPE_PERIODIC ) {
126161 return IPX_ERR_ARG ;
127162 }
128163
@@ -140,4 +175,3 @@ ipx_cpipe_send_term(ipx_ctx_t *ctx, enum ipx_cpipe_type type)
140175 errno = errno_backup ;
141176 return (rc == -1 ) ? IPX_ERR_DENIED : IPX_OK ;
142177}
143-
0 commit comments