Root/
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 <linux/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 | setup_timer(&sk->sk_timer, dn_slow_timer, (unsigned long)sk); |
40 | sk_reset_timer(sk, &sk->sk_timer, jiffies + SLOW_INTERVAL); |
41 | } |
42 | |
43 | void dn_stop_slow_timer(struct sock *sk) |
44 | { |
45 | sk_stop_timer(sk, &sk->sk_timer); |
46 | } |
47 | |
48 | static void dn_slow_timer(unsigned long arg) |
49 | { |
50 | struct sock *sk = (struct sock *)arg; |
51 | struct dn_scp *scp = DN_SK(sk); |
52 | |
53 | bh_lock_sock(sk); |
54 | |
55 | if (sock_owned_by_user(sk)) { |
56 | sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ / 10); |
57 | goto out; |
58 | } |
59 | |
60 | /* |
61 | * The persist timer is the standard slow timer used for retransmits |
62 | * in both connection establishment and disconnection as well as |
63 | * in the RUN state. The different states are catered for by changing |
64 | * the function pointer in the socket. Setting the timer to a value |
65 | * of zero turns it off. We allow the persist_fxn to turn the |
66 | * timer off in a permant way by returning non-zero, so that |
67 | * timer based routines may remove sockets. This is why we have a |
68 | * sock_hold()/sock_put() around the timer to prevent the socket |
69 | * going away in the middle. |
70 | */ |
71 | if (scp->persist && scp->persist_fxn) { |
72 | if (scp->persist <= SLOW_INTERVAL) { |
73 | scp->persist = 0; |
74 | |
75 | if (scp->persist_fxn(sk)) |
76 | goto out; |
77 | } else { |
78 | scp->persist -= SLOW_INTERVAL; |
79 | } |
80 | } |
81 | |
82 | /* |
83 | * Check for keepalive timeout. After the other timer 'cos if |
84 | * the previous timer caused a retransmit, we don't need to |
85 | * do this. scp->stamp is the last time that we sent a packet. |
86 | * The keepalive function sends a link service packet to the |
87 | * other end. If it remains unacknowledged, the standard |
88 | * socket timers will eventually shut the socket down. Each |
89 | * time we do this, scp->stamp will be updated, thus |
90 | * we won't try and send another until scp->keepalive has passed |
91 | * since the last successful transmission. |
92 | */ |
93 | if (scp->keepalive && scp->keepalive_fxn && (scp->state == DN_RUN)) { |
94 | if ((jiffies - scp->stamp) >= scp->keepalive) |
95 | scp->keepalive_fxn(sk); |
96 | } |
97 | |
98 | sk_reset_timer(sk, &sk->sk_timer, jiffies + SLOW_INTERVAL); |
99 | out: |
100 | bh_unlock_sock(sk); |
101 | sock_put(sk); |
102 | } |
103 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9