summaryrefslogtreecommitdiff
path: root/libhurd-cap-server/client-release.c
diff options
context:
space:
mode:
Diffstat (limited to 'libhurd-cap-server/client-release.c')
-rw-r--r--libhurd-cap-server/client-release.c192
1 files changed, 0 insertions, 192 deletions
diff --git a/libhurd-cap-server/client-release.c b/libhurd-cap-server/client-release.c
deleted file mode 100644
index 57d3796..0000000
--- a/libhurd-cap-server/client-release.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* client-release.c - Release a capability client.
- Copyright (C) 2004 Free Software Foundation, Inc.
- Written by Marcus Brinkmann <marcus@gnu.org>
-
- This file is part of the GNU Hurd.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this program; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdlib.h>
-
-#include <compiler.h>
-
-#include "cap-server-intern.h"
-
-
-/* Deallocate the connection client CLIENT. */
-void
-_hurd_cap_client_dealloc (hurd_cap_bucket_t bucket, _hurd_cap_client_t client)
-{
- unsigned int nr_caps = 0;
-
- /* This function is only invoked if the reference count for the
- client entry in the client table of the class drops to 0, and
- after the table entry was removed. Usually, the last reference
- is removed by the task death notification handler.
-
- At that point, there are no more pending RPCs for this client (if
- there were, there would be a reference for each of them). This
- also means that all capability IDs have at most one internal
- reference, the one for all external references. */
-
- /* Note that although the client has been removed from the clients
- table in the class, there are still back-references for each and
- every capability object in our capability table caps. These
- capability entries all count as references to ourself. They are
- used for example if a capability is revoked. It is important to
- realize that such a revocation can happen anytime as long as
- there are still valid capability objects in the caps table of the
- client.
-
- So, to correctly release those references, we have to look up
- each capability object properly, acquiring our own internal
- reference for it, then we have to unlock the client to lock the
- capability object, to finally revoke our own capability and
- release the capability object reference. Only then can we
- reacquire our own lock and go on to the next capability. While
- we do not hold our lock, more capabilities can be revoked by
- other concurrent operations. However, no new capabilities are
- added, so one pass through the table is enough. */
-
- pthread_mutex_lock (&client->lock);
-
- /* Release all capability objects held by this user. Because we
- have to honor the locking order, this takes a while. */
- HURD_TABLE_ITERATE (&client->caps, idx)
- {
- _hurd_cap_obj_entry_t entry;
-
- entry = *((_hurd_cap_obj_entry_t *)
- HURD_TABLE_LOOKUP (&client->caps, idx));
-
- /* If there were no external references, the last internal
- reference would have been released before we get here. */
- assert (entry->external_refs);
-
- nr_caps++;
-
- /* The number of internal references is either one or zero. If
- it is one, then the capability is not revoked yet, so we have
- to do it. If it is zero, then the capability is revoked
- (dead), and we only have to clear the table entry. */
- if (!entry->dead)
- {
- hurd_cap_obj_t cap_obj = entry->cap_obj;
-
- assert (entry->internal_refs == 1);
-
- /* Acquire an internal reference to prevent that our own
- reference to the capability object is removed by a
- concurrent revocation as soon as we unlock the client.
- After all, the existing internal reference belongs to the
- capability object, and not to us. */
- entry->internal_refs++;
- pthread_mutex_unlock (&client->lock);
-
- pthread_mutex_lock (&cap_obj->lock);
- /* Check if we should revoke it, or if somebody else did already. */
- if (!entry->dead)
- {
- int found;
-
- /* We should revoke it. */
- pthread_mutex_lock (&client->lock);
- found = hurd_ihash_remove (&client->caps_reverse,
- (hurd_ihash_key_t) cap_obj);
- assert (found);
- entry->dead = 1;
-
- assert (entry->internal_refs == 2);
- entry->internal_refs--;
- pthread_mutex_unlock (&client->lock);
-
- /* FIXME: Remove it from the capabilities client list. */
- }
- pthread_mutex_unlock (&cap_obj->lock);
-
- pthread_mutex_lock (&client->lock);
- /* Now we can drop the capability object below. */
- assert (entry->dead);
- assert (entry->internal_refs == 1);
- assert (entry->external_refs);
- }
- else
- {
- /* If the capability is dead, we can simply drop it below. */
- assert (entry->internal_refs == 0);
- entry->internal_refs = 1;
- }
-
- entry->dead = 0;
- /* ENTRY->internal_refs is 1. */
- entry->external_refs = 1;
-
- /* Remove the entry. */
- hurd_slab_dealloc (&_hurd_cap_obj_entry_space, entry);
- hurd_table_remove (&client->caps, idx);
- }
-
- /* After all this ugly work, the rest is trivial. */
- if (client->state != _HURD_CAP_STATE_GREEN)
- client->state = _HURD_CAP_STATE_GREEN;
-
- assert (client->pending_rpcs == NULL);
-
- /* FIXME: Release the task info capability here. */
-
- /* FIXME: It would be a good idea to shrink the empty table and
- empty hash here, to reclaim resources and be able to eventually
- enforce a per-client quota. */
- pthread_mutex_unlock (&client->lock);
-
- pthread_mutex_lock (&bucket->lock);
- bucket->nr_caps -= nr_caps;
- pthread_mutex_unlock (&bucket->lock);
-
- hurd_slab_dealloc (&_hurd_cap_client_space, client);
-}
-
-
-/* Release a reference for the client with the ID IDX in bucket
- BUCKET. */
-void
-_hurd_cap_client_release (hurd_cap_bucket_t bucket, _hurd_cap_client_id_t idx)
-{
- _hurd_cap_client_t client;
-
- pthread_mutex_lock (&bucket->lock);
- client = *(_hurd_cap_client_t *) HURD_TABLE_LOOKUP (&bucket->clients, idx);
-
- if (EXPECT_TRUE (client->refs > 1))
- {
- client->refs--;
- pthread_mutex_unlock (&bucket->lock);
- }
- else
- {
- hurd_table_remove (&bucket->clients, idx);
- hurd_ihash_locp_remove (&bucket->clients_reverse, client->locp);
-
- pthread_mutex_unlock (&bucket->lock);
- _hurd_cap_client_dealloc (bucket, client);
- }
-}