summaryrefslogtreecommitdiff
path: root/debian/patches/libports-current_rpcs_lock.patch
blob: c3b711021511f1fba65fcc0b886dd5badd21f026 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
commit 7ad61adbc08e3dabb9d36b2464324edaeb02f936
Author: Justus Winter <4winter@informatik.uni-hamburg.de>
Date:   Sun May 4 16:09:28 2014 +0200

    libports: more awesome
    
    XXX Richard thinks it's a gnumach bug.
    
    * libports/ports.h (struct port_info): Add current_rpcs_lock.
    * libports/create-internal.c (_ports_create_port_internal):
    Initialize current_rpcs_lock.
    * libports/import-port.c: Likewise.
    * libports/begin-rpc.c: Protect access to the list using the lock.
    * libports/inhibit-all-rpcs.c: Likewise.
    * libports/inhibit-bucket-rpcs.c: Likewise.
    * libports/inhibit-class-rpcs.c: Likewise.
    * libports/inhibit-port-rpcs.c: Likewise.
    * libports/interrupt-on-notify.c: Likewise.
    * libports/interrupt-rpcs.c: Likewise.

diff --git a/libports/begin-rpc.c b/libports/begin-rpc.c
index de58b06..8140ce5 100644
--- a/libports/begin-rpc.c
+++ b/libports/begin-rpc.c
@@ -91,12 +91,14 @@ ports_begin_rpc (void *portstruct, mach_msg_id_t msg_id, struct rpc_info *info)
   
   /* Record that that an RPC is in progress */
   info->thread = hurd_thread_self ();
+  pthread_mutex_lock (&pi->current_rpcs_lock);
   info->next = pi->current_rpcs;
   info->notifies = 0;
   if (pi->current_rpcs)
     pi->current_rpcs->prevp = &info->next;
   info->prevp = &pi->current_rpcs;
   pi->current_rpcs = info;
+  pthread_mutex_unlock (&pi->current_rpcs_lock);
 
   pi->class->rpcs++;
   pi->bucket->rpcs++;
diff --git a/libports/create-internal.c b/libports/create-internal.c
index 2c62ca6..361b453 100644
--- a/libports/create-internal.c
+++ b/libports/create-internal.c
@@ -60,6 +60,7 @@ _ports_create_port_internal (struct port_class *class,
   pi->flags = 0;
   pi->port_right = port;
   pi->current_rpcs = 0;
+  pthread_mutex_init (&pi->current_rpcs_lock, NULL);
   pi->bucket = bucket;
   
   pthread_mutex_lock (&_ports_global_lock);
diff --git a/libports/import-port.c b/libports/import-port.c
index 7bd331d..4847516 100644
--- a/libports/import-port.c
+++ b/libports/import-port.c
@@ -54,6 +54,7 @@ ports_import_port (struct port_class *class, struct port_bucket *bucket,
   pi->flags = stat.mps_srights ? PORT_HAS_SENDRIGHTS : 0;
   pi->port_right = port;
   pi->current_rpcs = 0;
+  pthread_mutex_init (&pi->current_rpcs_lock, NULL);
   pi->bucket = bucket;
   
   pthread_mutex_lock (&_ports_global_lock);
diff --git a/libports/inhibit-all-rpcs.c b/libports/inhibit-all-rpcs.c
index 421dc4a..4d43023 100644
--- a/libports/inhibit-all-rpcs.c
+++ b/libports/inhibit-all-rpcs.c
@@ -42,6 +42,7 @@ ports_inhibit_all_rpcs ()
 	  struct rpc_info *rpc;
 	  struct port_info *pi = portstruct;
 
+	  pthread_mutex_lock (&pi->current_rpcs_lock);
 	  for (rpc = pi->current_rpcs; rpc; rpc = rpc->next)
 	    {
 	      /* Avoid cancelling the calling thread if it's currently
@@ -51,6 +52,7 @@ ports_inhibit_all_rpcs ()
 	      else
 		hurd_thread_cancel (rpc->thread);
 	    }
+	  pthread_mutex_unlock (&pi->current_rpcs_lock);
 	}
       pthread_mutex_unlock (&_ports_htable_lock);
 
diff --git a/libports/inhibit-bucket-rpcs.c b/libports/inhibit-bucket-rpcs.c
index ee6000e..d7ffdc2 100644
--- a/libports/inhibit-bucket-rpcs.c
+++ b/libports/inhibit-bucket-rpcs.c
@@ -43,6 +43,7 @@ ports_inhibit_bucket_rpcs (struct port_bucket *bucket)
 	  if (pi->bucket != bucket)
 	    continue;
 
+	  pthread_mutex_lock (&pi->current_rpcs_lock);
 	  for (rpc = pi->current_rpcs; rpc; rpc = rpc->next)
 	    {
 	      /* Avoid cancelling the calling thread.  */
@@ -51,6 +52,7 @@ ports_inhibit_bucket_rpcs (struct port_bucket *bucket)
 	      else
 		hurd_thread_cancel (rpc->thread);
 	    }
+	  pthread_mutex_unlock (&pi->current_rpcs_lock);
 	}
       pthread_mutex_unlock (&_ports_htable_lock);
 
diff --git a/libports/inhibit-class-rpcs.c b/libports/inhibit-class-rpcs.c
index 0019b37..5243a2b 100644
--- a/libports/inhibit-class-rpcs.c
+++ b/libports/inhibit-class-rpcs.c
@@ -44,6 +44,7 @@ ports_inhibit_class_rpcs (struct port_class *class)
 	  if (pi->class != class)
 	    continue;
 
+	  pthread_mutex_lock (&pi->current_rpcs_lock);
 	  for (rpc = pi->current_rpcs; rpc; rpc = rpc->next)
 	    {
 	      /* Avoid cancelling the calling thread.  */
@@ -52,6 +53,7 @@ ports_inhibit_class_rpcs (struct port_class *class)
 	      else
 		hurd_thread_cancel (rpc->thread);
 	    }
+	  pthread_mutex_unlock (&pi->current_rpcs_lock);
 	}
       pthread_mutex_unlock (&_ports_htable_lock);
 
diff --git a/libports/inhibit-port-rpcs.c b/libports/inhibit-port-rpcs.c
index f712ca9..7479a50 100644
--- a/libports/inhibit-port-rpcs.c
+++ b/libports/inhibit-port-rpcs.c
@@ -35,7 +35,8 @@ ports_inhibit_port_rpcs (void *portstruct)
     {
       struct rpc_info *rpc;
       struct rpc_info *this_rpc = 0;
-  
+
+      pthread_mutex_lock (&pi->current_rpcs_lock);
       for (rpc = pi->current_rpcs; rpc; rpc = rpc->next)
 	{
 	  /* Avoid cancelling the calling thread.  */
@@ -57,6 +58,7 @@ ports_inhibit_port_rpcs (void *portstruct)
 	      break;
 	    }
 	}
+      pthread_mutex_unlock (&pi->current_rpcs_lock);
 
       pi->flags &= ~PORT_INHIBIT_WAIT;
       if (! err)
diff --git a/libports/interrupt-on-notify.c b/libports/interrupt-on-notify.c
index 7b93429..2118e4b 100644
--- a/libports/interrupt-on-notify.c
+++ b/libports/interrupt-on-notify.c
@@ -170,11 +170,11 @@ ports_interrupt_self_on_notification (void *object,
   struct port_info *pi = object;
   thread_t thread = hurd_thread_self ();
 
-  pthread_mutex_lock (&_ports_global_lock);
+  pthread_mutex_lock (&pi->current_rpcs_lock);
   for (rpc = pi->current_rpcs; rpc; rpc = rpc->next)
     if (rpc->thread == thread)
       break;
-  pthread_mutex_unlock (&_ports_global_lock);
+  pthread_mutex_unlock (&pi->current_rpcs_lock);
 
   assert (rpc);
 
diff --git a/libports/interrupt-rpcs.c b/libports/interrupt-rpcs.c
index 3dc3777..bc6e8f7 100644
--- a/libports/interrupt-rpcs.c
+++ b/libports/interrupt-rpcs.c
@@ -27,13 +27,13 @@ ports_interrupt_rpcs (void *portstruct)
   struct port_info *pi = portstruct;
   struct rpc_info *rpc;
 
-  pthread_mutex_lock (&_ports_global_lock);
-  
+  pthread_mutex_lock (&pi->current_rpcs_lock);
+
   for (rpc = pi->current_rpcs; rpc; rpc = rpc->next)
     {
       hurd_thread_cancel (rpc->thread);
       _ports_record_interruption (rpc);
     }
 
-  pthread_mutex_unlock (&_ports_global_lock);
+  pthread_mutex_unlock (&pi->current_rpcs_lock);
 }
diff --git a/libports/ports.h b/libports/ports.h
index ea99a7f..d26df42 100644
--- a/libports/ports.h
+++ b/libports/ports.h
@@ -48,6 +48,7 @@ struct port_info
   int flags;
   mach_port_t port_right;
   struct rpc_info *current_rpcs;
+  pthread_mutex_t current_rpcs_lock;
   struct port_bucket *bucket;
   hurd_ihash_locp_t hentry;
 };