linux-old/net/ipv4/timer.c
<<
>>
Prefs
   1/*
   2 * INET         An implementation of the TCP/IP protocol suite for the LINUX
   3 *              operating system.  INET is implemented using the  BSD Socket
   4 *              interface as the means of communication with the user level.
   5 *
   6 *              TIMER - implementation of software timers for IP.
   7 *
   8 * Version:     $Id: timer.c,v 1.15 1999/02/22 13:54:29 davem Exp $
   9 *
  10 * Authors:     Ross Biro, <bir7@leland.Stanford.Edu>
  11 *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  12 *              Corey Minyard <wf-rch!minyard@relay.EU.net>
  13 *              Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de>
  14 *              Florian La Roche, <flla@stud.uni-sb.de>
  15 *
  16 * Fixes:
  17 *              Alan Cox        :       To avoid destroying a wait queue as we use it
  18 *                                      we defer destruction until the destroy timer goes
  19 *                                      off.
  20 *              Alan Cox        :       Destroy socket doesn't write a status value to the
  21 *                                      socket buffer _AFTER_ freeing it! Also sock ensures
  22 *                                      the socket will get removed BEFORE this is called
  23 *                                      otherwise if the timer TIME_DESTROY occurs inside
  24 *                                      of inet_bh() with this socket being handled it goes
  25 *                                      BOOM! Have to stop timer going off if net_bh is
  26 *                                      active or the destroy causes crashes.
  27 *              Alan Cox        :       Cleaned up unused code.
  28 *
  29 *              This program is free software; you can redistribute it and/or
  30 *              modify it under the terms of the GNU General Public License
  31 *              as published by the Free Software Foundation; either version
  32 *              2 of the License, or (at your option) any later version.
  33 */
  34
  35#include <linux/types.h>
  36#include <linux/errno.h>
  37#include <linux/socket.h>
  38#include <linux/in.h>
  39#include <linux/kernel.h>
  40#include <linux/sched.h>
  41#include <linux/timer.h>
  42#include <asm/system.h>
  43#include <linux/interrupt.h>
  44#include <linux/inet.h>
  45#include <linux/netdevice.h>
  46#include <net/ip.h>
  47#include <net/protocol.h>
  48#include <net/tcp.h>
  49#include <linux/skbuff.h>
  50#include <net/sock.h>
  51#include <net/arp.h>
  52
  53void net_delete_timer (struct sock *t)
  54{
  55        if(t->timer.prev)
  56                del_timer (&t->timer);
  57        t->timeout = 0;
  58}
  59
  60void net_reset_timer (struct sock *t, int timeout, unsigned long len)
  61{
  62        t->timeout = timeout;
  63        mod_timer(&t->timer, jiffies+len);
  64}
  65
  66/* Now we will only be called whenever we need to do
  67 * something, but we must be sure to process all of the
  68 * sockets that need it.
  69 */
  70void net_timer (unsigned long data)
  71{
  72        struct sock *sk = (struct sock*)data;
  73        int why = sk->timeout;
  74
  75        /* Only process if socket is not in use. */
  76        if (atomic_read(&sk->sock_readers)) {
  77                /* Try again later. */ 
  78                mod_timer(&sk->timer, jiffies+HZ/20);
  79                return;
  80        }
  81
  82        /* Always see if we need to send an ack. */
  83        if (sk->tp_pinfo.af_tcp.delayed_acks && !sk->zapped) {
  84                sk->prot->read_wakeup (sk);
  85                if (!sk->dead)
  86                        sk->data_ready(sk,0);
  87        }
  88
  89        /* Now we need to figure out why the socket was on the timer. */
  90        switch (why) {
  91                case TIME_DONE:
  92                        /* If the socket hasn't been closed off, re-try a bit later. */
  93                        if (!sk->dead) {
  94                                net_reset_timer(sk, TIME_DONE, TCP_DONE_TIME);
  95                                break;
  96                        }
  97
  98                        if (sk->state != TCP_CLOSE) {
  99                                printk (KERN_DEBUG "non CLOSE socket in time_done\n");
 100                                break;
 101                        }
 102                        destroy_sock (sk);
 103                        break;
 104
 105                case TIME_DESTROY:
 106                        /* We've waited for a while for all the memory associated with
 107                         * the socket to be freed.
 108                         */
 109                        destroy_sock(sk);
 110                        break;
 111
 112                case TIME_CLOSE:
 113                        /* We've waited long enough, close the socket. */
 114                        tcp_set_state(sk, TCP_CLOSE);
 115                        sk->shutdown = SHUTDOWN_MASK;
 116                        if (!sk->dead)
 117                                sk->state_change(sk);
 118                        net_reset_timer (sk, TIME_DONE, TCP_DONE_TIME);
 119                        break;
 120
 121                default:
 122                        /* I want to see these... */
 123                        printk ("net_timer: timer expired - reason %d is unknown\n", why);
 124                        break;
 125        }
 126}
 127
 128
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.