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
|
From a266ace960cb823532140e2c683316a9b803a7a4 Mon Sep 17 00:00:00 2001
From: Justus Winter <4winter@informatik.uni-hamburg.de>
Date: Sun, 12 Oct 2014 15:32:54 +0200
Subject: [PATCH hurd 25/29] maybe_fu use pp
---
libports/complete-deallocate.c | 9 +++------
libports/destroy-right.c | 32 ++++++++++++--------------------
2 files changed, 15 insertions(+), 26 deletions(-)
diff --git a/libports/complete-deallocate.c b/libports/complete-deallocate.c
index 1a6eb54..6799dfd 100644
--- a/libports/complete-deallocate.c
+++ b/libports/complete-deallocate.c
@@ -27,7 +27,7 @@ _ports_complete_deallocate (struct port_info *pi)
{
assert ((pi->flags & PORT_HAS_SENDRIGHTS) == 0);
- if (pi->port_right)
+ if (MACH_PORT_VALID (pi->port_right))
{
struct references result;
@@ -45,11 +45,8 @@ _ports_complete_deallocate (struct port_info *pi)
hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry);
pthread_rwlock_unlock (&_ports_htable_lock);
- /* If the right has been destroyed using ports_destroy_right,
- port_right is set to MACH_PORT_DEAD. */
- if (MACH_PORT_VALID (pi->port_right))
- mach_port_mod_refs (mach_task_self (), pi->port_right,
- MACH_PORT_RIGHT_RECEIVE, -1);
+ mach_port_mod_refs (mach_task_self (), pi->port_right,
+ MACH_PORT_RIGHT_RECEIVE, -1);
pi->port_right = MACH_PORT_NULL;
}
diff --git a/libports/destroy-right.c b/libports/destroy-right.c
index 1e32379..ed6b66b 100644
--- a/libports/destroy-right.c
+++ b/libports/destroy-right.c
@@ -36,22 +36,21 @@ ports_destroy_right (void *portstruct)
struct port_info *pi = portstruct;
error_t err;
+ mach_port_clear_protected_payload (mach_task_self (),
+ pi->port_right);
+
pthread_mutex_lock (&_ports_lock);
if (pi->port_right != MACH_PORT_NULL)
{
- mach_port_clear_protected_payload (mach_task_self (),
- pi->port_right);
-
pthread_rwlock_wrlock (&_ports_htable_lock);
hurd_ihash_locp_remove (&_ports_htable, pi->ports_htable_entry);
hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry);
pthread_rwlock_unlock (&_ports_htable_lock);
+
err = mach_port_mod_refs (mach_task_self (), pi->port_right,
MACH_PORT_RIGHT_RECEIVE, -1);
assert_perror (err);
- pi->port_right = MACH_PORT_NULL;
-
if (pi->flags & PORT_HAS_SENDRIGHTS)
{
/* There are outstanding send rights, so we might get a
@@ -67,8 +66,6 @@ ports_destroy_right (void *portstruct)
reference here, but defer that instead. */
defer_dereferencing (pi);
}
- else
- hurd_ihash_locp_remove (&pi->bucket->htable, pi->hentry);
pi->port_right = MACH_PORT_DEAD;
}
@@ -117,20 +114,17 @@ gc_loop (void *arg)
while (d != NULL)
{
struct deferred_dereference *next = d->next;
- int references;
+ struct references refs;
- pthread_mutex_lock (&_ports_lock);
- references = d->pi->refcnt;
- pthread_mutex_unlock (&_ports_lock);
+ refcounts_references (&d->pi->refcounts, &refs);
- assert (references <= 2 || !"reference to destroyed right leaked");
+ // XXX: Need to think more about this.
+ assert (refs.hard <= 2 || !"reference to destroyed right leaked");
- if (references == 2)
+ if (refs.hard == 2)
{
+ /* XXX: does this actually happen? if so, why?? */
/* Get rid of the hash table reference. */
- pthread_mutex_lock (&_ports_lock);
- hurd_ihash_locp_remove (&d->pi->bucket->htable, d->pi->hentry);
- pthread_mutex_unlock (&_ports_lock);
ports_port_deref (d->pi);
}
@@ -177,15 +171,13 @@ defer_dereferencing (struct port_info *pi)
pthread_once (&once, start_gc);
- /* XXX we hold _ports_lock, so we cannot do
- ports_port_ref (pi); */
- pi->refcnt += 1;
+ ports_port_ref (pi);
d->pi = pi;
+ retry:
/* Append to the current generation. */
g = __atomic_load_n (&generation, __ATOMIC_RELAXED);
- retry:
d->next = __atomic_load_n (&generations[g], __ATOMIC_RELAXED);
if (! __atomic_compare_exchange_n (&generations[g], &d->next, d,
0, __ATOMIC_RELAXED, __ATOMIC_RELAXED))
--
2.1.3
|