LCOV - code coverage report
Current view: top level - netwerk/sctp/src/netinet - sctp_callout.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 64 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-
       2             :  * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
       3             :  * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
       4             :  * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions are met:
       8             :  *
       9             :  * a) Redistributions of source code must retain the above copyright notice,
      10             :  *    this list of conditions and the following disclaimer.
      11             :  *
      12             :  * b) Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in
      14             :  *    the documentation and/or other materials provided with the distribution.
      15             :  *
      16             :  * c) Neither the name of Cisco Systems, Inc. nor the names of its
      17             :  *    contributors may be used to endorse or promote products derived
      18             :  *    from this software without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
      22             :  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      23             :  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
      24             :  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      25             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      26             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      27             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      28             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      29             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
      30             :  * THE POSSIBILITY OF SUCH DAMAGE.
      31             :  */
      32             : 
      33             : #if defined(__Userspace__)
      34             : #include <sys/types.h>
      35             : #if !defined (__Userspace_os_Windows)
      36             : #include <sys/wait.h>
      37             : #include <unistd.h>
      38             : #include <pthread.h>
      39             : #endif
      40             : #if defined(__Userspace_os_NaCl)
      41             : #include <sys/select.h>
      42             : #endif
      43             : #include <stdlib.h>
      44             : #include <string.h>
      45             : #include <stdio.h>
      46             : #include <errno.h>
      47             : #include <netinet/sctp_sysctl.h>
      48             : #include <netinet/sctp_pcb.h>
      49             : #else
      50             : #include <netinet/sctp_os.h>
      51             : #include <netinet/sctp_callout.h>
      52             : #include <netinet/sctp_pcb.h>
      53             : #endif
      54             : 
      55             : /*
      56             :  * Callout/Timer routines for OS that doesn't have them
      57             :  */
      58             : #if defined(__APPLE__) || defined(__Userspace__)
      59             : int ticks = 0;
      60             : #else
      61             : extern int ticks;
      62             : #endif
      63             : 
      64             : /*
      65             :  * SCTP_TIMERQ_LOCK protects:
      66             :  * - SCTP_BASE_INFO(callqueue)
      67             :  * - sctp_os_timer_next: next timer to check
      68             :  */
      69             : static sctp_os_timer_t *sctp_os_timer_next = NULL;
      70             : 
      71             : void
      72           0 : sctp_os_timer_init(sctp_os_timer_t *c)
      73             : {
      74           0 :         bzero(c, sizeof(*c));
      75           0 : }
      76             : 
      77             : void
      78           0 : sctp_os_timer_start(sctp_os_timer_t *c, int to_ticks, void (*ftn) (void *),
      79             :                     void *arg)
      80             : {
      81             :         /* paranoia */
      82           0 :         if ((c == NULL) || (ftn == NULL))
      83           0 :             return;
      84             : 
      85           0 :         SCTP_TIMERQ_LOCK();
      86             :         /* check to see if we're rescheduling a timer */
      87           0 :         if (c->c_flags & SCTP_CALLOUT_PENDING) {
      88           0 :                 if (c == sctp_os_timer_next) {
      89           0 :                         sctp_os_timer_next = TAILQ_NEXT(c, tqe);
      90             :                 }
      91           0 :                 TAILQ_REMOVE(&SCTP_BASE_INFO(callqueue), c, tqe);
      92             :                 /*
      93             :                  * part of the normal "stop a pending callout" process
      94             :                  * is to clear the CALLOUT_ACTIVE and CALLOUT_PENDING
      95             :                  * flags.  We don't bother since we are setting these
      96             :                  * below and we still hold the lock.
      97             :                  */
      98             :         }
      99             : 
     100             :         /*
     101             :          * We could unlock/splx here and lock/spl at the TAILQ_INSERT_TAIL,
     102             :          * but there's no point since doing this setup doesn't take much time.
     103             :          */
     104           0 :         if (to_ticks <= 0)
     105           0 :                 to_ticks = 1;
     106             : 
     107           0 :         c->c_arg = arg;
     108           0 :         c->c_flags = (SCTP_CALLOUT_ACTIVE | SCTP_CALLOUT_PENDING);
     109           0 :         c->c_func = ftn;
     110           0 :         c->c_time = ticks + to_ticks;
     111           0 :         TAILQ_INSERT_TAIL(&SCTP_BASE_INFO(callqueue), c, tqe);
     112           0 :         SCTP_TIMERQ_UNLOCK();
     113             : }
     114             : 
     115             : int
     116           0 : sctp_os_timer_stop(sctp_os_timer_t *c)
     117             : {
     118           0 :         SCTP_TIMERQ_LOCK();
     119             :         /*
     120             :          * Don't attempt to delete a callout that's not on the queue.
     121             :          */
     122           0 :         if (!(c->c_flags & SCTP_CALLOUT_PENDING)) {
     123           0 :                 c->c_flags &= ~SCTP_CALLOUT_ACTIVE;
     124           0 :                 SCTP_TIMERQ_UNLOCK();
     125           0 :                 return (0);
     126             :         }
     127           0 :         c->c_flags &= ~(SCTP_CALLOUT_ACTIVE | SCTP_CALLOUT_PENDING);
     128           0 :         if (c == sctp_os_timer_next) {
     129           0 :                 sctp_os_timer_next = TAILQ_NEXT(c, tqe);
     130             :         }
     131           0 :         TAILQ_REMOVE(&SCTP_BASE_INFO(callqueue), c, tqe);
     132           0 :         SCTP_TIMERQ_UNLOCK();
     133           0 :         return (1);
     134             : }
     135             : 
     136             : static void
     137           0 : sctp_handle_tick(int delta)
     138             : {
     139             :         sctp_os_timer_t *c;
     140             :         void (*c_func)(void *);
     141             :         void *c_arg;
     142             : 
     143           0 :         SCTP_TIMERQ_LOCK();
     144             :         /* update our tick count */
     145           0 :         ticks += delta;
     146           0 :         c = TAILQ_FIRST(&SCTP_BASE_INFO(callqueue));
     147           0 :         while (c) {
     148           0 :                 if (c->c_time <= ticks) {
     149           0 :                         sctp_os_timer_next = TAILQ_NEXT(c, tqe);
     150           0 :                         TAILQ_REMOVE(&SCTP_BASE_INFO(callqueue), c, tqe);
     151           0 :                         c_func = c->c_func;
     152           0 :                         c_arg = c->c_arg;
     153           0 :                         c->c_flags &= ~SCTP_CALLOUT_PENDING;
     154           0 :                         SCTP_TIMERQ_UNLOCK();
     155           0 :                         c_func(c_arg);
     156           0 :                         SCTP_TIMERQ_LOCK();
     157           0 :                         c = sctp_os_timer_next;
     158             :                 } else {
     159           0 :                         c = TAILQ_NEXT(c, tqe);
     160             :                 }
     161             :         }
     162           0 :         sctp_os_timer_next = NULL;
     163           0 :         SCTP_TIMERQ_UNLOCK();
     164           0 : }
     165             : 
     166             : #if defined(__APPLE__)
     167             : void
     168             : sctp_timeout(void *arg SCTP_UNUSED)
     169             : {
     170             :         sctp_handle_tick(SCTP_BASE_VAR(sctp_main_timer_ticks));
     171             :         sctp_start_main_timer();
     172             : }
     173             : #endif
     174             : 
     175             : #if defined(__Userspace__)
     176             : #define TIMEOUT_INTERVAL 10
     177             : 
     178             : void *
     179           0 : user_sctp_timer_iterate(void *arg)
     180             : {
     181           0 :         for (;;) {
     182             : #if defined (__Userspace_os_Windows)
     183             :                 Sleep(TIMEOUT_INTERVAL);
     184             : #else
     185             :                 struct timeval timeout;
     186             : 
     187           0 :                 timeout.tv_sec  = 0;
     188           0 :                 timeout.tv_usec = 1000 * TIMEOUT_INTERVAL;
     189           0 :                 select(0, NULL, NULL, NULL, &timeout);
     190             : #endif
     191           0 :                 if (SCTP_BASE_VAR(timer_thread_should_exit)) {
     192           0 :                         break;
     193             :                 }
     194           0 :                 sctp_handle_tick(MSEC_TO_TICKS(TIMEOUT_INTERVAL));
     195             :         }
     196           0 :         return (NULL);
     197             : }
     198             : 
     199             : void
     200           0 : sctp_start_timer(void)
     201             : {
     202             :         /*
     203             :          * No need to do SCTP_TIMERQ_LOCK_INIT();
     204             :          * here, it is being done in sctp_pcb_init()
     205             :          */
     206             : #if defined (__Userspace_os_Windows)
     207             :         if ((SCTP_BASE_VAR(timer_thread) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)user_sctp_timer_iterate, NULL, 0, NULL)) == NULL) {
     208             :                 SCTP_PRINTF("ERROR; Creating ithread failed\n");
     209             :         }
     210             : #else
     211             :         int rc;
     212             : 
     213           0 :         rc = pthread_create(&SCTP_BASE_VAR(timer_thread), NULL, user_sctp_timer_iterate, NULL);
     214           0 :         if (rc) {
     215           0 :                 SCTP_PRINTF("ERROR; return code from pthread_create() is %d\n", rc);
     216             :         }
     217             : #endif
     218           0 : }
     219             : 
     220             : #endif

Generated by: LCOV version 1.13