diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /net/decnet/dn_timer.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'net/decnet/dn_timer.c')
-rw-r--r-- | net/decnet/dn_timer.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/net/decnet/dn_timer.c b/net/decnet/dn_timer.c new file mode 100644 index 000000000000..09825711d58a --- /dev/null +++ b/net/decnet/dn_timer.c | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * DECnet An implementation of the DECnet protocol suite for the LINUX | ||
3 | * operating system. DECnet is implemented using the BSD Socket | ||
4 | * interface as the means of communication with the user level. | ||
5 | * | ||
6 | * DECnet Socket Timer Functions | ||
7 | * | ||
8 | * Author: Steve Whitehouse <SteveW@ACM.org> | ||
9 | * | ||
10 | * | ||
11 | * Changes: | ||
12 | * Steve Whitehouse : Made keepalive timer part of the same | ||
13 | * timer idea. | ||
14 | * Steve Whitehouse : Added checks for sk->sock_readers | ||
15 | * David S. Miller : New socket locking | ||
16 | * Steve Whitehouse : Timer grabs socket ref. | ||
17 | */ | ||
18 | #include <linux/net.h> | ||
19 | #include <linux/socket.h> | ||
20 | #include <linux/skbuff.h> | ||
21 | #include <linux/netdevice.h> | ||
22 | #include <linux/timer.h> | ||
23 | #include <linux/spinlock.h> | ||
24 | #include <net/sock.h> | ||
25 | #include <asm/atomic.h> | ||
26 | #include <net/flow.h> | ||
27 | #include <net/dn.h> | ||
28 | |||
29 | /* | ||
30 | * Slow timer is for everything else (n * 500mS) | ||
31 | */ | ||
32 | |||
33 | #define SLOW_INTERVAL (HZ/2) | ||
34 | |||
35 | static void dn_slow_timer(unsigned long arg); | ||
36 | |||
37 | void dn_start_slow_timer(struct sock *sk) | ||
38 | { | ||
39 | sk->sk_timer.expires = jiffies + SLOW_INTERVAL; | ||
40 | sk->sk_timer.function = dn_slow_timer; | ||
41 | sk->sk_timer.data = (unsigned long)sk; | ||
42 | |||
43 | add_timer(&sk->sk_timer); | ||
44 | } | ||
45 | |||
46 | void dn_stop_slow_timer(struct sock *sk) | ||
47 | { | ||
48 | del_timer(&sk->sk_timer); | ||
49 | } | ||
50 | |||
51 | static void dn_slow_timer(unsigned long arg) | ||
52 | { | ||
53 | struct sock *sk = (struct sock *)arg; | ||
54 | struct dn_scp *scp = DN_SK(sk); | ||
55 | |||
56 | sock_hold(sk); | ||
57 | bh_lock_sock(sk); | ||
58 | |||
59 | if (sock_owned_by_user(sk)) { | ||
60 | sk->sk_timer.expires = jiffies + HZ / 10; | ||
61 | add_timer(&sk->sk_timer); | ||
62 | goto out; | ||
63 | } | ||
64 | |||
65 | /* | ||
66 | * The persist timer is the standard slow timer used for retransmits | ||
67 | * in both connection establishment and disconnection as well as | ||
68 | * in the RUN state. The different states are catered for by changing | ||
69 | * the function pointer in the socket. Setting the timer to a value | ||
70 | * of zero turns it off. We allow the persist_fxn to turn the | ||
71 | * timer off in a permant way by returning non-zero, so that | ||
72 | * timer based routines may remove sockets. This is why we have a | ||
73 | * sock_hold()/sock_put() around the timer to prevent the socket | ||
74 | * going away in the middle. | ||
75 | */ | ||
76 | if (scp->persist && scp->persist_fxn) { | ||
77 | if (scp->persist <= SLOW_INTERVAL) { | ||
78 | scp->persist = 0; | ||
79 | |||
80 | if (scp->persist_fxn(sk)) | ||
81 | goto out; | ||
82 | } else { | ||
83 | scp->persist -= SLOW_INTERVAL; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | * Check for keepalive timeout. After the other timer 'cos if | ||
89 | * the previous timer caused a retransmit, we don't need to | ||
90 | * do this. scp->stamp is the last time that we sent a packet. | ||
91 | * The keepalive function sends a link service packet to the | ||
92 | * other end. If it remains unacknowledged, the standard | ||
93 | * socket timers will eventually shut the socket down. Each | ||
94 | * time we do this, scp->stamp will be updated, thus | ||
95 | * we won't try and send another until scp->keepalive has passed | ||
96 | * since the last successful transmission. | ||
97 | */ | ||
98 | if (scp->keepalive && scp->keepalive_fxn && (scp->state == DN_RUN)) { | ||
99 | if ((jiffies - scp->stamp) >= scp->keepalive) | ||
100 | scp->keepalive_fxn(sk); | ||
101 | } | ||
102 | |||
103 | sk->sk_timer.expires = jiffies + SLOW_INTERVAL; | ||
104 | |||
105 | add_timer(&sk->sk_timer); | ||
106 | out: | ||
107 | bh_unlock_sock(sk); | ||
108 | sock_put(sk); | ||
109 | } | ||