Merge lp:~brandontschaefer/libertine/rlist-race into lp:libertine

Proposed by Brandon Schaefer
Status: Merged
Approved by: Christopher Townsend
Approved revision: 287
Merged at revision: 288
Proposed branch: lp:~brandontschaefer/libertine/rlist-race
Merge into: lp:libertine
Diff against target: 51 lines (+8/-6)
1 file modified
python/libertine/Libertine.py (+8/-6)
To merge this branch: bzr merge lp:~brandontschaefer/libertine/rlist-race
Reviewer Review Type Date Requested Status
Christopher Townsend Approve
Libertine CI Bot continuous-integration Approve
Review via email: mp+303058@code.launchpad.net

Commit message

Fix a race when two sockets in the read list from select were pairs and the first one closed its connection.

Description of the change

How this happens:
1) We get two sockets in the read list from select
2) Both those sockets are pairs (ie. read from 1 send to 2)
3) The first socket has its connection closed (ie. recv gave us 0 data)
4) Then when the second socket reads data to send to the first socket that was closed
   it is not found since it was just cleaned up.

The current fix:
Check if our socket is not in the session sockets or in the pairs. If thats true we stopped watching this socket so skip to the next read!

To post a comment you must log in.
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:287
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/100/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/286
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=default/236
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/236
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=yakkety,testname=default/236
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=vivid+overlay,testname=default/236
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/236
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=yakkety,testname=default/236
    None: https://jenkins.canonical.com/libertine/job/lp-generic-update-mp/217/console
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/288
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=vivid+overlay/272
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=xenial+overlay/272
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=yakkety/272
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=vivid+overlay/265
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=vivid+overlay/265/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/265
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/265/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=yakkety/265
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=yakkety/265/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=vivid+overlay/265
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=vivid+overlay/265/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/265
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/265/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=yakkety/265
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=yakkety/265/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/100/rebuild

review: Approve (continuous-integration)
Revision history for this message
Christopher Townsend (townsend) wrote :

Yes, race is indeed fixed. Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'python/libertine/Libertine.py'
2--- python/libertine/Libertine.py 2016-08-11 17:07:44 +0000
3+++ python/libertine/Libertine.py 2016-08-16 18:18:12 +0000
4@@ -444,7 +444,6 @@
5 class Socket(object):
6 """
7 A simple socket wrapper class. This will wrap a socket
8- This is used for RAII and to take ownership of the socket
9
10 :param socket: A python socket to be wrapped
11 """
12@@ -454,10 +453,6 @@
13
14 self.socket = sock
15
16- def __del__(self):
17- self.socket.shutdown(SHUT_RDWR)
18- self.socket.close()
19-
20 """
21 Implement equality checking for other instances of this class or ints only.
22
23@@ -485,6 +480,7 @@
24 class SessionSocket(Socket):
25 """
26 Creates a AF_UNIX socket from a path to be used as the session socket.
27+ This is used for RAII and to take ownership of the socket
28
29 :param path: The path the socket will be binded with
30 """
31@@ -507,7 +503,8 @@
32 self.session_path = session_path
33
34 def __del__(self):
35- super().__del__()
36+ self.socket.shutdown(SHUT_RDWR)
37+ self.socket.close()
38 os.remove(self.session_path)
39
40
41@@ -600,6 +597,11 @@
42 if sock.fileno() == -1:
43 continue
44
45+ # Its possible to have multiple socket reads that are pairs. If this happens and we remove a pair we
46+ # need to ignore the other pair since it no longer has a complete pair
47+ if sock.fileno() not in self.host_session_socket_path_map and sock.fileno() not in self.socket_pairs:
48+ continue
49+
50 if sock.fileno() in self.host_session_socket_path_map:
51 self.accept_new_connection(self.host_session_socket_path_map[sock.fileno()], sock)
52

Subscribers

People subscribed via source and target branches