"Fossies" - the Fresh Open Source Software Archive

Member "open-fcoe-3.19/fcoe-utils/lib/sa_select.c" (15 Apr 2015, 5115 Bytes) of package /linux/misc/open-fcoe-3.19.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sa_select.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright(c) 2009 Intel Corporation. All rights reserved.
    3  *
    4  * This program is free software; you can redistribute it and/or modify it
    5  * under the terms and conditions of the GNU General Public License,
    6  * version 2, as published by the Free Software Foundation.
    7  *
    8  * This program is distributed in the hope it will be useful, but WITHOUT
    9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   11  * more details.
   12  *
   13  * You should have received a copy of the GNU General Public License along with
   14  * this program; if not, write to the Free Software Foundation, Inc.,
   15  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
   16  *
   17  * Maintained at www.Open-FCoE.org
   18  */
   19 
   20 #include "fcoemon_utils.h"
   21 #include "net_types.h"
   22 #include "fc_types.h"
   23 
   24 #define NFC_NFDS        64
   25 
   26 /*
   27 * Static module state.
   28 */
   29 static struct sa_sel_state {
   30     fd_set      ts_rx_fds;
   31     fd_set      ts_tx_fds;
   32     fd_set      ts_ex_fds;
   33     int         ts_max_fd;
   34     int         ts_sig;
   35     struct sa_sel_fd {
   36         void    (*ts_rx_handler)(void *);
   37         void    (*ts_tx_handler)(void *);
   38         void    (*ts_ex_handler)(void *);
   39         void    *ts_handler_arg;
   40     } ts_fd[NFC_NFDS];
   41     void        (*ts_callback)(void);
   42 } sa_sel_state;
   43 
   44 /**
   45  * sa_select_loop() - listens to registered descriptors
   46  *
   47  * Return value:
   48  *  -1 on failure or interrupted signal number
   49  */
   50 int sa_select_loop(void)
   51 {
   52     struct sa_sel_state *ss = &sa_sel_state;
   53     struct sa_sel_fd *fp;
   54     fd_set rx_fds;
   55     fd_set tx_fds;
   56     fd_set ex_fds;
   57     struct timeval tval;
   58     struct timeval *tvp;
   59     int rv, i;
   60 
   61     ss->ts_sig = 0;
   62     while (ss->ts_sig == 0) {
   63         sa_timer_check(&tval);
   64         if (ss->ts_sig)
   65             break;
   66         if (tval.tv_sec == 0 && tval.tv_usec == 0)
   67             tvp = NULL;
   68         else
   69             tvp = &tval;
   70         rx_fds = ss->ts_rx_fds;
   71         tx_fds = ss->ts_tx_fds;
   72         ex_fds = ss->ts_ex_fds;
   73         rv = select(ss->ts_max_fd + 1, &rx_fds, &tx_fds, &ex_fds, tvp);
   74         if (rv == -1) {
   75             if (errno == EINTR)
   76                 continue;
   77             return rv;
   78         }
   79 
   80         fp = ss->ts_fd;
   81         for (i = 0; rv > 0 && i <= sa_sel_state.ts_max_fd; i++, fp++) {
   82             if (FD_ISSET(i, &rx_fds)) {
   83                 if (fp->ts_rx_handler != NULL)
   84                     (*fp->ts_rx_handler)
   85                     (fp->ts_handler_arg);
   86                 else {
   87                     ASSERT(!FD_ISSET(i, &ss->ts_rx_fds));
   88                 }
   89                 --rv;
   90             }
   91             if (FD_ISSET(i, &tx_fds)) {
   92                 if (fp->ts_tx_handler != NULL)
   93                     (*fp->ts_tx_handler)
   94                     (fp->ts_handler_arg);
   95                 else {
   96                     ASSERT(!FD_ISSET(i, &ss->ts_tx_fds));
   97                 }
   98                 --rv;
   99             }
  100             if (FD_ISSET(i, &ex_fds)) {
  101                 if (fp->ts_ex_handler != NULL)
  102                     (*fp->ts_ex_handler)
  103                     (fp->ts_handler_arg);
  104                 else {
  105                     ASSERT(!FD_ISSET(i, &ss->ts_ex_fds));
  106                 }
  107                 --rv;
  108             }
  109         }
  110         if (ss->ts_callback != NULL)
  111             (*ss->ts_callback)();
  112     }
  113     return ss->ts_sig;
  114 }
  115 
  116 void
  117 sa_select_add_fd(int fd,
  118          void (*rx_handler)(void *),
  119          void (*tx_handler)(void *),
  120          void (*ex_handler)(void *),
  121          void *arg)
  122 {
  123     struct sa_sel_state *ss = &sa_sel_state;
  124     struct sa_sel_fd *fp;
  125 
  126     ASSERT_NOTIMPL(fd < NFC_NFDS);
  127     ASSERT(rx_handler != NULL || tx_handler != NULL || ex_handler != NULL);
  128     if (ss->ts_max_fd < fd)
  129         ss->ts_max_fd = fd;
  130     fp = &ss->ts_fd[fd];
  131     fp->ts_handler_arg = arg;
  132     if (rx_handler != NULL) {
  133         fp->ts_rx_handler = rx_handler;
  134         FD_SET(fd, &ss->ts_rx_fds);
  135     }
  136     if (tx_handler != NULL) {
  137         fp->ts_tx_handler = tx_handler;
  138         FD_SET(fd, &ss->ts_tx_fds);
  139     }
  140     if (ex_handler != NULL) {
  141         fp->ts_ex_handler = ex_handler;
  142         FD_SET(fd, &ss->ts_ex_fds);
  143     }
  144 }
  145 
  146 void
  147 sa_select_set_rx(int fd, void (*handler)(void *))
  148 {
  149     struct sa_sel_state *ss = &sa_sel_state;
  150 
  151     ASSERT(fd <= ss->ts_max_fd);
  152     ss->ts_fd[fd].ts_rx_handler = handler;
  153     if (handler != NULL)
  154         FD_SET(fd, &ss->ts_rx_fds);
  155     else
  156         FD_CLR(fd, &ss->ts_rx_fds);
  157 }
  158 
  159 void
  160 sa_select_set_tx(int fd, void (*handler)(void *))
  161 {
  162     struct sa_sel_state *ss = &sa_sel_state;
  163 
  164     ASSERT(fd <= ss->ts_max_fd);
  165     ss->ts_fd[fd].ts_tx_handler = handler;
  166     if (handler != NULL)
  167         FD_SET(fd, &ss->ts_tx_fds);
  168     else
  169         FD_CLR(fd, &ss->ts_tx_fds);
  170 }
  171 
  172 void
  173 sa_select_set_ex(int fd, void (*handler)(void *))
  174 {
  175     struct sa_sel_state *ss = &sa_sel_state;
  176 
  177     ASSERT(fd <= ss->ts_max_fd);
  178     ss->ts_fd[fd].ts_ex_handler = handler;
  179     if (handler != NULL)
  180         FD_SET(fd, &ss->ts_ex_fds);
  181     else
  182         FD_CLR(fd, &ss->ts_ex_fds);
  183 }
  184 
  185 void
  186 sa_select_rem_fd(int fd)
  187 {
  188     struct sa_sel_state *ss = &sa_sel_state;
  189     struct sa_sel_fd *fp;
  190 
  191     ASSERT_NOTIMPL(fd < NFC_NFDS);
  192     FD_CLR(fd, &ss->ts_rx_fds);
  193     FD_CLR(fd, &ss->ts_tx_fds);
  194     FD_CLR(fd, &ss->ts_ex_fds);
  195     fp = &ss->ts_fd[fd];
  196     fp->ts_rx_handler = NULL;
  197     fp->ts_tx_handler = NULL;
  198     fp->ts_ex_handler = NULL;
  199     fp->ts_handler_arg = NULL;
  200 }
  201 
  202 /*
  203  * Set callback for every time through the select loop.
  204  */
  205 void
  206 sa_select_set_callback(void (*cb)(void))
  207 {
  208     sa_sel_state.ts_callback = cb;
  209 }
  210 
  211 /*
  212  * Cause select loop to exit.
  213  * This is invoked from a handler which wants the select loop to return
  214  * after the handler is finished.  For example, during receipt of a network
  215  * packet, the program may decide to clean up and exit, but in order to do
  216  * this cleanly, all lower-level protocol handlers should return first.
  217  */
  218 void
  219 sa_select_exit(int sig)
  220 {
  221     sa_sel_state.ts_sig = sig;
  222 }