~aptdaemon-developers/aptdaemon/ubuntu-lucid

« back to all changes in this revision

Viewing changes to debian/patches/02_fix-455861.patch

  • Committer: Michael Vogt
  • Date: 2010-03-16 16:01:56 UTC
  • Revision ID: michael.vogt@ubuntu.com-20100316160156-ibbpm2yf1dtfw4qw
* debian/patches/02_fix-455861.patch:
  - merge patch from james_w to fix race in debconf socket
    code (many thanks) LP: #455861

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
=== modified file 'aptdaemon/debconf.py'
 
2
--- aptdaemon/debconf.py        2009-10-02 11:27:03 +0000
 
3
+++ aptdaemon/debconf.py        2010-03-15 02:05:34 +0000
 
4
@@ -33,6 +33,7 @@
 
5
 import socket
 
6
 import subprocess
 
7
 import tempfile
 
8
+import threading
 
9
 
 
10
 import gobject
 
11
 
 
12
@@ -65,6 +66,8 @@
 
13
         self._listener_id = None
 
14
         self._active_conn = None
 
15
         self._watch_ids = []
 
16
+        self._socket_lock = threading.Lock()
 
17
+        self._socket_closed = False
 
18
 
 
19
     def _get_debconf_env(self):
 
20
         """Returns a dictonary of the environment variables required by
 
21
@@ -88,40 +91,51 @@
 
22
     def stop(self):
 
23
         """Stop listening on the socket."""
 
24
         logging.debug("debconf.stop()")
 
25
-        self.socket.close()
 
26
-        # ensure outstanding gio messages are processed
 
27
-        context = glib.main_context_default()
 
28
-        while context.pending():
 
29
-            context.iteration()
 
30
-        gobject.source_remove(self._listener_id)
 
31
-        self._listener_id = None
 
32
+        self._socket_lock.acquire()
 
33
+        try:
 
34
+            self.socket.close()
 
35
+            self._socket_closed = True
 
36
+            # ensure outstanding gio messages are processed
 
37
+            context = glib.main_context_default()
 
38
+            while context.pending():
 
39
+                context.iteration()
 
40
+            gobject.source_remove(self._listener_id)
 
41
+            self._listener_id = None
 
42
+        finally:
 
43
+            self._socket_lock.release()
 
44
 
 
45
     def _accept_connection(self, source, condition):
 
46
         """Callback for new connections of the passthrough frontend."""
 
47
         log.debug("New passthrough connection")
 
48
-        # ensure outstanding gio messages are processed (to ensure
 
49
-        # that _hangup was run on the previous connection, see LP: #432607)
 
50
-        context = glib.main_context_default()
 
51
-        while context.pending():
 
52
-            context.iteration()
 
53
-        if self._active_conn:
 
54
-            raise IOError, "Multiple debconf connections not supported"
 
55
-        conn, addr = source.accept()
 
56
-        self._active_conn = conn
 
57
-        self.helper = subprocess.Popen(["debconf-communicate"],
 
58
-                                       stdin=subprocess.PIPE,
 
59
-                                       stdout=subprocess.PIPE,
 
60
-                                       env=self._get_debconf_env())
 
61
-        w = gobject.io_add_watch(conn, gobject.IO_IN|gobject.IO_HUP|gobject.IO_ERR,
 
62
-                             self._copy_conn, self.helper.stdin)
 
63
-        self._watch_ids.append(w)
 
64
-        w= gobject.io_add_watch(self.helper.stdout, gobject.IO_IN,
 
65
-                             self._copy_stdout, conn)
 
66
-        self._watch_ids.append(w)
 
67
-        w = gobject.io_add_watch(self.helper.stdout, gobject.IO_HUP|gobject.IO_ERR,
 
68
-                             self._hangup)
 
69
-        self._watch_ids.append(w)
 
70
-        return True
 
71
+        self._socket_lock.acquire()
 
72
+        try:
 
73
+            # ensure outstanding gio messages are processed (to ensure
 
74
+            # that _hangup was run on the previous connection, see LP: #432607)
 
75
+            context = glib.main_context_default()
 
76
+            while context.pending():
 
77
+                context.iteration()
 
78
+            if self._socket_closed:
 
79
+                return True
 
80
+            if self._active_conn:
 
81
+                raise IOError, "Multiple debconf connections not supported"
 
82
+            conn, addr = source.accept()
 
83
+            self._active_conn = conn
 
84
+            self.helper = subprocess.Popen(["debconf-communicate"],
 
85
+                                           stdin=subprocess.PIPE,
 
86
+                                           stdout=subprocess.PIPE,
 
87
+                                           env=self._get_debconf_env())
 
88
+            w = gobject.io_add_watch(conn, gobject.IO_IN|gobject.IO_HUP|gobject.IO_ERR,
 
89
+                                 self._copy_conn, self.helper.stdin)
 
90
+            self._watch_ids.append(w)
 
91
+            w= gobject.io_add_watch(self.helper.stdout, gobject.IO_IN,
 
92
+                                 self._copy_stdout, conn)
 
93
+            self._watch_ids.append(w)
 
94
+            w = gobject.io_add_watch(self.helper.stdout, gobject.IO_HUP|gobject.IO_ERR,
 
95
+                                 self._hangup)
 
96
+            self._watch_ids.append(w)
 
97
+            return True
 
98
+        finally:
 
99
+            self._socket_lock.release()
 
100
 
 
101
     def _hangup(self, source, condition):
 
102
         """Callback when the debconf-communicate program exists 
 
103