summaryrefslogtreecommitdiff
path: root/libhurd-cap-server/client-create.c
diff options
context:
space:
mode:
Diffstat (limited to 'libhurd-cap-server/client-create.c')
-rw-r--r--libhurd-cap-server/client-create.c213
1 files changed, 0 insertions, 213 deletions
diff --git a/libhurd-cap-server/client-create.c b/libhurd-cap-server/client-create.c
deleted file mode 100644
index ac8c54a..0000000
--- a/libhurd-cap-server/client-create.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/* client-create.c - Create a capability client.
- Copyright (C) 2004, 2005 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 <assert.h>
-#include <pthread.h>
-#include <stdlib.h>
-
-#include "cap-server-intern.h"
-
-
-/* Client management code. */
-
-/* Allocate a new capability client structure for the slab cache. */
-static error_t
-_hurd_cap_client_constructor (void *hook, void *buffer)
-{
- _hurd_cap_client_t client = (_hurd_cap_client_t) buffer;
- error_t err;
-
- err = pthread_mutex_init (&client->lock, NULL);
- if (err)
- return err;
-
- client->state = _HURD_CAP_STATE_GREEN;
- client->pending_rpcs = NULL;
-
- /* Capabilities are mapped to clients many to many, so we can not
- use a location pointer. However, this is not critical as
- removing an entry only blocks out RPCs for the same client, and
- not others. */
- hurd_ihash_init (&client->caps_reverse, HURD_IHASH_NO_LOCP);
-
- return 0;
-
- /* This is provided here in case you add more initialization to the
- end of the above code. */
-#if 0
- pthread_mutex_destroy (&client->lock);
-
- return err;
-#endif
-}
-
-
-/* Allocate a new capability client structure for the slab cache. */
-static void
-_hurd_cap_client_destructor (void *hook, void *buffer)
-{
- _hurd_cap_client_t client = (_hurd_cap_client_t) buffer;
-
- hurd_ihash_destroy (&client->caps_reverse);
- hurd_table_destroy (&client->caps);
- pthread_mutex_destroy (&client->lock);
-}
-
-
-/* The global slab for all capability clients. */
-struct hurd_slab_space _hurd_cap_client_space
- = HURD_SLAB_SPACE_INITIALIZER (struct _hurd_cap_client, NULL, NULL,
- _hurd_cap_client_constructor,
- _hurd_cap_client_destructor, NULL);
-
-
-static error_t
-_hurd_cap_client_alloc (hurd_task_id_t task_id,
- _hurd_cap_client_t *r_client)
-{
- error_t err;
- void *new_client;
- _hurd_cap_client_t client;
-
- err = hurd_slab_alloc (&_hurd_cap_client_space, &new_client);
- if (err)
- return err;
-
- client = new_client;
-
- /* CLIENT->id will be initialized by the caller when adding the
- client to the client table of the class. */
- client->task_id = task_id;
-
- err = hurd_table_init (&client->caps, sizeof (_hurd_cap_obj_entry_t));
- if (err)
- {
- free (client);
- return err;
- }
-
- /* FIXME: We need to acquire a task info capability here. The task
- death notifications have been suspended by the caller. */
-
- *r_client = client;
- return 0;
-}
-
-
-/* Look up the client with the task ID TASK in the bucket BUCKET, and
- return it in R_CLIENT, with one additional reference. If it is not
- found, create it. */
-error_t
-__attribute__((visibility("hidden")))
-_hurd_cap_client_create (hurd_cap_bucket_t bucket,
- hurd_task_id_t task_id,
- _hurd_cap_client_t *r_client)
-{
- error_t err = 0;
- _hurd_cap_client_t client;
-
- pthread_mutex_lock (&bucket->lock);
- client = (_hurd_cap_client_t) hurd_ihash_find (&bucket->clients_reverse,
- task_id);
- if (client)
- {
- if (client->dead)
- err = EINVAL; /* FIXME: A more appropriate code? */
- else
- {
- client->refs++;
- *r_client = client;
- }
- pthread_mutex_unlock (&bucket->lock);
- return err;
- }
- pthread_mutex_unlock (&bucket->lock);
-
- /* The client is not yet registered. Block out processing task
- death notifications, create a new client structure, and then
- enter it into the table before resuming task death
- notifications. */
- hurd_task_death_notify_suspend ();
- err = _hurd_cap_client_alloc (task_id, r_client);
- if (err)
- {
- hurd_task_death_notify_resume ();
- return err;
- }
-
- pthread_mutex_lock (&bucket->lock);
- /* Since we dropped the bucket lock during the allocation (which is
- potentially long) we need to check that somebody else didn't
- already allocate a client data structure. If so, we can just use
- that. Otherwise, we continue. */
- client = (_hurd_cap_client_t) hurd_ihash_find (&bucket->clients_reverse,
- task_id);
- if (client)
- {
- if (client->dead)
- {
- err = EINVAL; /* FIXME: A more appropriate code? */
- pthread_mutex_unlock (&bucket->lock);
- }
- else
- {
- /* Somebody else was indeed faster. Use the existing entry. */
- client->refs++;
- pthread_mutex_unlock (&bucket->lock);
- _hurd_cap_client_dealloc (bucket, *r_client);
- *r_client = client;
- }
- return err;
- }
-
- client = *r_client;
-
- /* One reference for the fact that the client task lives, one for
- the caller. */
- client->refs = 2;
-
- err = hurd_table_enter (&bucket->clients, &client, &client->id);
- if (!err)
- {
- err = hurd_ihash_add (&bucket->clients_reverse, task_id, client);
- if (err)
- hurd_table_remove (&bucket->clients, client->id);
- }
- if (err)
- {
- pthread_mutex_unlock (&bucket->lock);
- hurd_task_death_notify_resume ();
-
- _hurd_cap_client_dealloc (bucket, client);
- return err;
- }
- pthread_mutex_unlock (&bucket->lock);
- hurd_task_death_notify_resume ();
-
- *r_client = client;
-
- return 0;
-}