diff options
author | Allan Stephens <allan.stephens@windriver.com> | 2008-04-15 00:22:02 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-15 00:22:02 -0700 |
commit | 0c3141e910eaaa0b617e2f26c69b266d1cd1f035 (patch) | |
tree | 53b9f635b8dc2bf82d49e2d29f6e07677fa4811e /net/tipc/port.c | |
parent | b89741a0cc162511b4341c07e17e1bd4c8b4621d (diff) | |
download | linux-0c3141e910eaaa0b617e2f26c69b266d1cd1f035.tar.gz linux-0c3141e910eaaa0b617e2f26c69b266d1cd1f035.tar.bz2 linux-0c3141e910eaaa0b617e2f26c69b266d1cd1f035.zip |
[TIPC]: Overhaul of socket locking logic
This patch modifies TIPC's socket code to follow the same approach
used by other protocols. This change eliminates the need for a
mutex in the TIPC-specific portion of the socket protocol data
structure -- in its place, the standard Linux socket backlog queue
and associated locking routines are utilized. These changes fix
a long-standing receive queue bug on SMP systems, and also enable
individual read and write threads to utilize a socket without
unnecessarily interfering with each other.
Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/port.c')
-rw-r--r-- | net/tipc/port.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c index e2646a96935d..2f5806410c64 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -1240,6 +1240,28 @@ exit: return res; } +/** + * tipc_disconnect_port - disconnect port from peer + * + * Port must be locked. + */ + +int tipc_disconnect_port(struct tipc_port *tp_ptr) +{ + int res; + + if (tp_ptr->connected) { + tp_ptr->connected = 0; + /* let timer expire on it's own to avoid deadlock! */ + tipc_nodesub_unsubscribe( + &((struct port *)tp_ptr)->subscription); + res = TIPC_OK; + } else { + res = -ENOTCONN; + } + return res; +} + /* * tipc_disconnect(): Disconnect port form peer. * This is a node local operation. @@ -1248,17 +1270,12 @@ exit: int tipc_disconnect(u32 ref) { struct port *p_ptr; - int res = -ENOTCONN; + int res; p_ptr = tipc_port_lock(ref); if (!p_ptr) return -EINVAL; - if (p_ptr->publ.connected) { - p_ptr->publ.connected = 0; - /* let timer expire on it's own to avoid deadlock! */ - tipc_nodesub_unsubscribe(&p_ptr->subscription); - res = TIPC_OK; - } + res = tipc_disconnect_port((struct tipc_port *)p_ptr); tipc_port_unlock(p_ptr); return res; } |