128 |
{ |
{ |
129 |
error_t err = 0; |
error_t err = 0; |
130 |
_hurd_cap_client_t client; |
_hurd_cap_client_t client; |
|
_hurd_cap_client_entry_t entry; |
|
|
struct _hurd_cap_client_entry new_entry; |
|
131 |
|
|
132 |
pthread_mutex_lock (&bucket->lock); |
pthread_mutex_lock (&bucket->lock); |
133 |
client = (_hurd_cap_client_t) hurd_ihash_find (&bucket->clients_reverse, |
client = (_hurd_cap_client_t) hurd_ihash_find (&bucket->clients_reverse, |
134 |
task_id); |
task_id); |
135 |
if (client) |
if (client) |
136 |
{ |
{ |
137 |
entry = (_hurd_cap_client_entry_t) |
if (client->dead) |
|
HURD_TABLE_LOOKUP (&bucket->clients, client->id); |
|
|
if (entry->dead) |
|
138 |
err = EINVAL; /* FIXME: A more appropriate code? */ |
err = EINVAL; /* FIXME: A more appropriate code? */ |
139 |
else |
else |
140 |
{ |
{ |
141 |
entry->refs++; |
client->refs++; |
142 |
*r_client = entry->client; |
*r_client = client; |
143 |
} |
} |
144 |
pthread_mutex_unlock (&bucket->lock); |
pthread_mutex_unlock (&bucket->lock); |
145 |
return err; |
return err; |
167 |
task_id); |
task_id); |
168 |
if (client) |
if (client) |
169 |
{ |
{ |
170 |
entry = (_hurd_cap_client_entry_t) |
if (client->dead) |
|
HURD_TABLE_LOOKUP (&bucket->clients, client->id); |
|
|
if (entry->dead) |
|
171 |
{ |
{ |
172 |
err = EINVAL; /* FIXME: A more appropriate code? */ |
err = EINVAL; /* FIXME: A more appropriate code? */ |
173 |
pthread_mutex_unlock (&bucket->lock); |
pthread_mutex_unlock (&bucket->lock); |
175 |
else |
else |
176 |
{ |
{ |
177 |
/* Somebody else was indeed faster. Use the existing entry. */ |
/* Somebody else was indeed faster. Use the existing entry. */ |
178 |
entry->refs++; |
client->refs++; |
179 |
pthread_mutex_unlock (&bucket->lock); |
pthread_mutex_unlock (&bucket->lock); |
180 |
_hurd_cap_client_dealloc (bucket, *r_client); |
_hurd_cap_client_dealloc (bucket, *r_client); |
181 |
*r_client = entry->client; |
*r_client = client; |
182 |
} |
} |
183 |
return err; |
return err; |
184 |
} |
} |
185 |
|
|
186 |
client = *r_client; |
client = *r_client; |
187 |
|
|
|
/* Enter the new client. */ |
|
|
new_entry.client = client; |
|
188 |
/* One reference for the fact that the client task lives, one for |
/* One reference for the fact that the client task lives, one for |
189 |
the caller. */ |
the caller. */ |
190 |
new_entry.refs = 2; |
client->refs = 2; |
191 |
|
|
192 |
err = hurd_table_enter (&bucket->clients, &new_entry, &client->id); |
err = hurd_table_enter (&bucket->clients, &client, &client->id); |
193 |
if (!err) |
if (!err) |
194 |
{ |
{ |
195 |
err = hurd_ihash_add (&bucket->clients_reverse, task_id, client); |
err = hurd_ihash_add (&bucket->clients_reverse, task_id, client); |