From 05b0fe74bb6eb10a49333d42f9f1677235863f85 Mon Sep 17 00:00:00 2001 From: Alexandra Ellwood Date: Tue, 12 Jun 2007 21:07:16 +0000 Subject: [PATCH] Add advisory locking to CCAPI Added code to trash client crashes. Reorganized server launch to make it easier to implement platform specific code. ticket: new status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19573 dc483132-0cff-0310-8789-dd5450dbe970 --- src/ccapi/server/ccs_array.c | 83 +++++++-- src/ccapi/server/ccs_array.h | 40 +++-- src/ccapi/server/ccs_client.c | 169 ++++++++++++++++++ src/ccapi/server/ccs_client.h | 47 +++++ src/ccapi/server/ccs_common.h | 2 + src/ccapi/server/ccs_lock.c | 85 ++++++--- src/ccapi/server/ccs_lock.h | 23 +-- src/ccapi/server/ccs_lock_state.c | 57 ++++-- src/ccapi/server/ccs_lock_state.h | 3 + src/ccapi/server/ccs_lockref.c | 121 +++++++++++++ src/ccapi/server/ccs_lockref.h | 44 +++++ src/ccapi/server/ccs_os_pipe.h | 11 +- src/ccapi/server/ccs_os_server.h | 6 + src/ccapi/server/ccs_pipe.c | 130 +------------- src/ccapi/server/ccs_pipe.h | 18 -- src/ccapi/server/ccs_server.c | 112 +++++++++--- src/ccapi/server/ccs_server.h | 12 +- src/ccapi/server/ccs_types.h | 16 +- src/ccapi/server/mac/ccs_os_pipe.c | 44 +---- .../server/mac/{main.c => ccs_os_server.c} | 163 ++++++++--------- 20 files changed, 793 insertions(+), 393 deletions(-) create mode 100644 src/ccapi/server/ccs_client.c create mode 100644 src/ccapi/server/ccs_client.h create mode 100644 src/ccapi/server/ccs_lockref.c create mode 100644 src/ccapi/server/ccs_lockref.h rename src/ccapi/server/mac/{main.c => ccs_os_server.c} (87%) diff --git a/src/ccapi/server/ccs_array.c b/src/ccapi/server/ccs_array.c index 682693341..7683c944c 100644 --- a/src/ccapi/server/ccs_array.c +++ b/src/ccapi/server/ccs_array.c @@ -29,53 +29,53 @@ /* ------------------------------------------------------------------------ */ -static cc_int32 ccs_pipe_object_release (void *io_pipe) +static cc_int32 ccs_client_object_release (void *io_client) { - return cci_check_error (ccs_pipe_release ((ccs_pipe_t) io_pipe)); + return cci_check_error (ccs_client_release ((ccs_client_t) io_client)); } /* ------------------------------------------------------------------------ */ -cc_int32 ccs_pipe_array_new (ccs_pipe_array_t *out_array) +cc_int32 ccs_client_array_new (ccs_client_array_t *out_array) { - return cci_array_new (out_array, ccs_pipe_object_release); + return cci_array_new (out_array, ccs_client_object_release); } /* ------------------------------------------------------------------------ */ -cc_int32 ccs_pipe_array_release (ccs_pipe_array_t io_array) +cc_int32 ccs_client_array_release (ccs_client_array_t io_array) { return cci_array_release (io_array); } /* ------------------------------------------------------------------------ */ -cc_uint64 ccs_pipe_array_count (ccs_pipe_array_t in_array) +cc_uint64 ccs_client_array_count (ccs_client_array_t in_array) { return cci_array_count (in_array); } /* ------------------------------------------------------------------------ */ -ccs_pipe_t ccs_pipe_array_object_at_index (ccs_pipe_array_t io_array, - cc_uint64 in_position) +ccs_client_t ccs_client_array_object_at_index (ccs_client_array_t io_array, + cc_uint64 in_position) { return cci_array_object_at_index (io_array, in_position); } /* ------------------------------------------------------------------------ */ -cc_int32 ccs_pipe_array_insert (ccs_pipe_array_t io_array, - ccs_pipe_t in_pipe, - cc_uint64 in_position) +cc_int32 ccs_client_array_insert (ccs_client_array_t io_array, + ccs_client_t in_client, + cc_uint64 in_position) { - return cci_array_insert (io_array, in_pipe, in_position); + return cci_array_insert (io_array, in_client, in_position); } /* ------------------------------------------------------------------------ */ -cc_int32 ccs_pipe_array_remove (ccs_pipe_array_t io_array, - cc_uint64 in_position) +cc_int32 ccs_client_array_remove (ccs_client_array_t io_array, + cc_uint64 in_position) { return cci_array_remove (io_array, in_position); } @@ -143,3 +143,58 @@ cc_int32 ccs_lock_array_move (ccs_lock_array_t io_array, { return cci_array_move (io_array, in_position, in_new_position, out_real_new_position); } + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lockref_object_release (void *io_lockref) +{ + return cci_check_error (ccs_lockref_release ((ccs_lockref_t) io_lockref)); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lockref_array_new (ccs_lockref_array_t *out_array) +{ + return cci_array_new (out_array, ccs_lockref_object_release); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lockref_array_release (ccs_lockref_array_t io_array) +{ + return cci_array_release (io_array); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint64 ccs_lockref_array_count (ccs_lockref_array_t in_array) +{ + return cci_array_count (in_array); +} + +/* ------------------------------------------------------------------------ */ + +ccs_lockref_t ccs_lockref_array_object_at_index (ccs_lockref_array_t io_array, + cc_uint64 in_position) +{ + return cci_array_object_at_index (io_array, in_position); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lockref_array_insert (ccs_lockref_array_t io_array, + ccs_lockref_t in_lockref, + cc_uint64 in_position) +{ + return cci_array_insert (io_array, in_lockref, in_position); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lockref_array_remove (ccs_lockref_array_t io_array, + cc_uint64 in_position) +{ + return cci_array_remove (io_array, in_position); +} diff --git a/src/ccapi/server/ccs_array.h b/src/ccapi/server/ccs_array.h index 6f896cb60..05bcbdf8e 100644 --- a/src/ccapi/server/ccs_array.h +++ b/src/ccapi/server/ccs_array.h @@ -29,21 +29,21 @@ #include "ccs_types.h" -cc_int32 ccs_pipe_array_new (ccs_pipe_array_t *out_array); +cc_int32 ccs_client_array_new (ccs_client_array_t *out_array); -cc_int32 ccs_pipe_array_release (ccs_pipe_array_t io_array); +cc_int32 ccs_client_array_release (ccs_client_array_t io_array); -cc_uint64 ccs_pipe_array_count (ccs_pipe_array_t in_array); +cc_uint64 ccs_client_array_count (ccs_client_array_t in_array); -ccs_pipe_t ccs_pipe_array_object_at_index (ccs_pipe_array_t io_array, - cc_uint64 in_position); +ccs_client_t ccs_client_array_object_at_index (ccs_client_array_t io_array, + cc_uint64 in_position); -cc_int32 ccs_pipe_array_insert (ccs_pipe_array_t io_array, - ccs_pipe_t in_pipe, - cc_uint64 in_position); +cc_int32 ccs_client_array_insert (ccs_client_array_t io_array, + ccs_client_t in_client, + cc_uint64 in_position); -cc_int32 ccs_pipe_array_remove (ccs_pipe_array_t io_array, - cc_uint64 in_position); +cc_int32 ccs_client_array_remove (ccs_client_array_t io_array, + cc_uint64 in_position); #pragma mark - @@ -68,4 +68,24 @@ cc_int32 ccs_lock_array_move (ccs_lock_array_t io_array, cc_uint64 in_new_position, cc_uint64 *out_real_new_position); +#pragma mark - + +cc_int32 ccs_lockref_object_release (void *io_lockref); + +cc_int32 ccs_lockref_array_new (ccs_lockref_array_t *out_array); + +cc_int32 ccs_lockref_array_release (ccs_lockref_array_t io_array); + +cc_uint64 ccs_lockref_array_count (ccs_lockref_array_t in_array); + +ccs_lockref_t ccs_lockref_array_object_at_index (ccs_lockref_array_t io_array, + cc_uint64 in_position); + +cc_int32 ccs_lockref_array_insert (ccs_lockref_array_t io_array, + ccs_lockref_t in_lockref, + cc_uint64 in_position); + +cc_int32 ccs_lockref_array_remove (ccs_lockref_array_t io_array, + cc_uint64 in_position); + #endif /* CCS_ARRAY_H */ diff --git a/src/ccapi/server/ccs_client.c b/src/ccapi/server/ccs_client.c new file mode 100644 index 000000000..f23792a58 --- /dev/null +++ b/src/ccapi/server/ccs_client.c @@ -0,0 +1,169 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +struct ccs_client_d { + ccs_pipe_t client_pipe; + ccs_lockref_array_t lockrefs; +}; + +struct ccs_client_d ccs_client_initializer = { CCS_PIPE_NULL, NULL }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_client_new (ccs_client_t *out_client, + ccs_pipe_t in_client_pipe) +{ + cc_int32 err = ccNoError; + ccs_client_t client = NULL; + + if (!out_client ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + client = malloc (sizeof (*client)); + if (client) { + *client = ccs_client_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = ccs_lockref_array_new (&client->lockrefs); + } + + if (!err) { + client->client_pipe = in_client_pipe; + + *out_client = client; + client = NULL; + } + + ccs_client_release (client); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_client_release (ccs_client_t io_client) +{ + cc_int32 err = ccNoError; + + if (!io_client) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + ccs_lockref_array_release (io_client->lockrefs); + free (io_client); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_client_add_lockref (ccs_client_t io_client, + ccs_lock_t in_lock) +{ + cc_int32 err = ccNoError; + ccs_lockref_t lockref = NULL; + + if (!io_client) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_lockref_new (&lockref, io_client, in_lock); + } + + if (!err) { + err = ccs_lockref_array_insert (io_client->lockrefs, lockref, + ccs_lockref_array_count (io_client->lockrefs)); + if (!err) { lockref = NULL; /* take ownership */ } + } + + ccs_lockref_release (lockref); + + return cci_check_error (err); +} + + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_client_remove_lockref (ccs_client_t io_client, + ccs_lock_t in_lock) +{ + cc_int32 err = ccNoError; + cc_uint32 found_lock = 0; + + if (!io_client) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cc_uint64 i; + cc_uint64 lock_count = ccs_lockref_array_count (io_client->lockrefs); + + for (i = 0; !err && i < lock_count; i++) { + ccs_lockref_t lockref = ccs_lockref_array_object_at_index (io_client->lockrefs, i); + + err = ccs_lockref_is_for_lock (lockref, in_lock, &found_lock); + + if (!err && found_lock) { + err = ccs_lockref_invalidate (lockref); + + if (!err) { + cci_debug_printf ("%s: Removing lockref %p.", __FUNCTION__, lockref); + err = ccs_lockref_array_remove (io_client->lockrefs, i); + break; + } + } + } + } + + if (!err && !found_lock) { + cci_debug_printf ("%s: WARNING! lockref not found.", __FUNCTION__); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_client_uses_pipe (ccs_client_t in_client, + ccs_pipe_t in_pipe, + cc_uint32 *out_uses_pipe) +{ + cc_int32 err = ccNoError; + + if (in_client ) { err = cci_check_error (ccErrBadParam); } + if (in_pipe ) { err = cci_check_error (ccErrBadParam); } + if (out_uses_pipe) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_uses_pipe = (in_client->client_pipe == in_pipe); + } + + return cci_check_error (err); +} diff --git a/src/ccapi/server/ccs_client.h b/src/ccapi/server/ccs_client.h new file mode 100644 index 000000000..3b6268247 --- /dev/null +++ b/src/ccapi/server/ccs_client.h @@ -0,0 +1,47 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_CLIENT_H +#define CCS_CLIENT_H + +#include "ccs_types.h" + +cc_int32 ccs_client_new (ccs_client_t *out_client, + ccs_pipe_t in_client_pipe); + +cc_int32 ccs_client_release (ccs_client_t io_client); + +cc_int32 ccs_client_add_lockref (ccs_client_t io_client, + ccs_lock_t in_lock); + +cc_int32 ccs_client_remove_lockref (ccs_client_t io_client, + ccs_lock_t in_lock); + +cc_int32 ccs_client_uses_pipe (ccs_client_t in_client, + ccs_pipe_t in_pipe, + cc_uint32 *out_uses_pipe); + +#endif /* CCS_CLIENT_H */ diff --git a/src/ccapi/server/ccs_common.h b/src/ccapi/server/ccs_common.h index f035780da..2013c9e10 100644 --- a/src/ccapi/server/ccs_common.h +++ b/src/ccapi/server/ccs_common.h @@ -39,6 +39,8 @@ #include "ccs_lock.h" #include "ccs_lock_state.h" #include "ccs_pipe.h" +#include "ccs_client.h" +#include "ccs_lockref.h" #include "ccs_server.h" #endif /* CCS_COMMON_H */ diff --git a/src/ccapi/server/ccs_lock.c b/src/ccapi/server/ccs_lock.c index 939da5e12..3fa761efd 100644 --- a/src/ccapi/server/ccs_lock.c +++ b/src/ccapi/server/ccs_lock.c @@ -32,24 +32,28 @@ struct ccs_lock_d { cc_int32 invalid_object_err; ccs_pipe_t client_pipe; ccs_pipe_t reply_pipe; + ccs_lock_state_t lock_state_owner; /* pointer to owner */ }; -struct ccs_lock_d ccs_lock_initializer = { 0, 1, 1, NULL, NULL }; +struct ccs_lock_d ccs_lock_initializer = { 0, 1, 1, CCS_PIPE_NULL, CCS_PIPE_NULL, NULL }; /* ------------------------------------------------------------------------ */ -cc_int32 ccs_lock_new (ccs_lock_t *out_lock, - cc_uint32 in_type, - cc_int32 in_invalid_object_err, - ccs_pipe_t in_client_pipe, - ccs_pipe_t in_reply_pipe) +cc_int32 ccs_lock_new (ccs_lock_t *out_lock, + cc_uint32 in_type, + cc_int32 in_invalid_object_err, + ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_lock_state_t in_lock_state_owner) { cc_int32 err = ccNoError; ccs_lock_t lock = NULL; + ccs_client_t client = NULL; if (!out_lock ) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + if (!in_lock_state_owner ) { err = cci_check_error (ccErrBadParam); } if (in_type != cc_lock_read && in_type != cc_lock_write && @@ -68,17 +72,20 @@ cc_int32 ccs_lock_new (ccs_lock_t *out_lock, } if (!err) { - err = ccs_pipe_copy (&lock->client_pipe, in_client_pipe); - } - - if (!err) { - err = ccs_pipe_copy (&lock->reply_pipe, in_reply_pipe); + err = ccs_server_client_for_pipe (in_client_pipe, &client); } if (!err) { + lock->client_pipe = in_client_pipe; + lock->reply_pipe = in_reply_pipe; lock->type = in_type; lock->invalid_object_err = in_invalid_object_err; - + lock->lock_state_owner = in_lock_state_owner; + + err = ccs_client_add_lockref (client, lock); + } + + if (!err) { *out_lock = lock; lock = NULL; } @@ -93,17 +100,26 @@ cc_int32 ccs_lock_new (ccs_lock_t *out_lock, cc_int32 ccs_lock_release (ccs_lock_t io_lock) { cc_int32 err = ccNoError; + ccs_client_t client = NULL; if (!io_lock) { err = cci_check_error (ccErrBadParam); } if (!err && io_lock->pending) { err = ccs_server_send_reply (io_lock->reply_pipe, io_lock->invalid_object_err, NULL); + + io_lock->pending = 0; + } + + if (!err) { + err = ccs_server_client_for_pipe (io_lock->client_pipe, &client); + } + + if (!err) { + err = ccs_client_remove_lockref (client, io_lock); } if (!err) { - ccs_pipe_release (io_lock->client_pipe); - ccs_pipe_release (io_lock->reply_pipe); free (io_lock); } @@ -112,6 +128,22 @@ cc_int32 ccs_lock_release (ccs_lock_t io_lock) /* ------------------------------------------------------------------------ */ +cc_int32 ccs_lock_invalidate (ccs_lock_t io_lock) +{ + cc_int32 err = ccNoError; + + if (!io_lock) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + io_lock->pending = 0; /* client is dead, don't try to talk to it */ + err = ccs_lock_state_invalidate_lock (io_lock->lock_state_owner, io_lock); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + cc_int32 ccs_lock_grant_lock (ccs_lock_t io_lock) { cc_int32 err = ccNoError; @@ -122,11 +154,13 @@ cc_int32 ccs_lock_grant_lock (ccs_lock_t io_lock) if (io_lock->pending) { err = ccs_server_send_reply (io_lock->reply_pipe, err, NULL); - if (!err) { - ccs_pipe_release (io_lock->reply_pipe); - io_lock->pending = 0; - io_lock->reply_pipe = NULL; + if (err) { + cci_debug_printf ("WARNING %s() called on a lock belonging to a dead client!", + __FUNCTION__); } + + io_lock->pending = 0; + io_lock->reply_pipe = CCS_PIPE_NULL; } else { cci_debug_printf ("WARNING %s() called on non-pending lock!", __FUNCTION__); @@ -208,19 +242,18 @@ cc_int32 ccs_lock_is_write_lock (ccs_lock_t in_lock, /* ------------------------------------------------------------------------ */ -cc_int32 ccs_lock_is_for_client (ccs_lock_t in_lock, - ccs_pipe_t in_client_pipe, - cc_uint32 *out_is_for_client) +cc_int32 ccs_lock_is_for_client_pipe (ccs_lock_t in_lock, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_is_for_client_pipe) { cc_int32 err = ccNoError; if (!in_lock ) { err = cci_check_error (ccErrBadParam); } - if (!out_is_for_client ) { err = cci_check_error (ccErrBadParam); } if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!out_is_for_client_pipe ) { err = cci_check_error (ccErrBadParam); } if (!err) { - err = ccs_pipe_compare (in_lock->client_pipe, in_client_pipe, - out_is_for_client); + *out_is_for_client_pipe = (in_lock->client_pipe == in_client_pipe); } return cci_check_error (err); @@ -229,8 +262,8 @@ cc_int32 ccs_lock_is_for_client (ccs_lock_t in_lock, /* ------------------------------------------------------------------------ */ -cc_int32 ccs_lock_client (ccs_lock_t in_lock, - ccs_pipe_t *out_client_pipe) +cc_int32 ccs_lock_client_pipe (ccs_lock_t in_lock, + ccs_pipe_t *out_client_pipe) { cc_int32 err = ccNoError; diff --git a/src/ccapi/server/ccs_lock.h b/src/ccapi/server/ccs_lock.h index 197f5d50d..bed0a9eab 100644 --- a/src/ccapi/server/ccs_lock.h +++ b/src/ccapi/server/ccs_lock.h @@ -29,14 +29,17 @@ #include "ccs_types.h" -cc_int32 ccs_lock_new (ccs_lock_t *out_lock, - cc_uint32 in_type, - cc_int32 in_invalid_object_err, - ccs_pipe_t in_client_pipe, - ccs_pipe_t in_reply_pipe); +cc_int32 ccs_lock_new (ccs_lock_t *out_lock, + cc_uint32 in_type, + cc_int32 in_invalid_object_err, + ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_lock_state_t in_lock_state_owner); cc_int32 ccs_lock_release (ccs_lock_t io_lock); +cc_int32 ccs_lock_invalidate (ccs_lock_t io_lock); + cc_int32 ccs_lock_grant_lock (ccs_lock_t io_lock); cc_uint32 ccs_lock_is_pending (ccs_lock_t in_lock, @@ -51,11 +54,11 @@ cc_int32 ccs_lock_is_read_lock (ccs_lock_t in_lock, cc_int32 ccs_lock_is_write_lock (ccs_lock_t in_lock, cc_uint32 *out_is_write_lock); -cc_int32 ccs_lock_is_for_client (ccs_lock_t in_lock, - ccs_pipe_t in_client_pipe, - cc_uint32 *out_is_for_client); +cc_int32 ccs_lock_is_for_client_pipe (ccs_lock_t in_lock, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_is_for_client_pipe); -cc_int32 ccs_lock_client (ccs_lock_t in_lock, - ccs_pipe_t *out_client_pipe); +cc_int32 ccs_lock_client_pipe (ccs_lock_t in_lock, + ccs_pipe_t *out_client_pipe); #endif /* CCS_LOCK_H */ diff --git a/src/ccapi/server/ccs_lock_state.c b/src/ccapi/server/ccs_lock_state.c index c90311f74..b8dc5debf 100644 --- a/src/ccapi/server/ccs_lock_state.c +++ b/src/ccapi/server/ccs_lock_state.c @@ -111,7 +111,8 @@ static cc_int32 ccs_lock_status_add_pending_lock (ccs_lock_state_t io_lock_stat if (!err) { err = ccs_lock_new (&lock, in_lock_type, io_lock_state->invalid_object_err, - in_client_pipe, in_reply_pipe); + in_client_pipe, in_reply_pipe, + io_lock_state); } if (!err) { @@ -211,8 +212,8 @@ static cc_int32 ccs_lock_state_check_pending_lock (ccs_lock_state_t io_lock_sta err = ccs_lock_type (lock, &lock_type); if (!err) { - err = ccs_lock_is_for_client (lock, in_pending_lock_client_pipe, - &lock_is_for_client); + err = ccs_lock_is_for_client_pipe (lock, in_pending_lock_client_pipe, + &lock_is_for_client); } if (!err) { @@ -287,16 +288,13 @@ static cc_int32 ccs_lock_state_check_pending_lock (ccs_lock_state_t io_lock_sta static cc_int32 ccs_lock_status_try_to_grant_pending_locks (ccs_lock_state_t io_lock_state) { cc_int32 err = ccNoError; - cc_uint32 done = 1; + cc_uint32 done = 0; if (!io_lock_state) { err = cci_check_error (ccErrBadParam); } - /* The lock array should now be in one of two states: empty or containing - * only read locks because if it contained a write lock we would have just - * deleted it. Look at the pending locks and see if we can grant them. - * Note that downgrade locks mean we must check all pending locks each pass - * since a downgrade lock might be last in the list. */ - + /* Look at the pending locks and see if we can grant them. + * Note that downgrade locks mean we must check all pending locks each pass + * since a downgrade lock might be last in the list. */ while (!err && !done) { cc_uint64 i; @@ -306,10 +304,10 @@ static cc_int32 ccs_lock_status_try_to_grant_pending_locks (ccs_lock_state_t io_ for (i = io_lock_state->first_pending_lock_index; !err && i < count; i++) { ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); cc_uint32 lock_type = 0; - ccs_pipe_t client_pipe = NULL; + ccs_pipe_t client_pipe = CCS_PIPE_NULL; cc_uint32 can_grant_lock_now = 0; - err = ccs_lock_client (lock, &client_pipe); + err = ccs_lock_client_pipe (lock, &client_pipe); if (!err) { err = ccs_lock_type (lock, &lock_type); @@ -365,7 +363,7 @@ cc_int32 ccs_lock_state_add (ccs_lock_state_t io_lock_state, ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); cc_uint32 has_pending_lock_for_client = 0; - err = ccs_lock_is_for_client (lock, in_client_pipe, &has_pending_lock_for_client); + err = ccs_lock_is_for_client_pipe (lock, in_client_pipe, &has_pending_lock_for_client); if (!err && has_pending_lock_for_client) { cci_debug_printf ("WARNING %s() removing pending lock for client.", __FUNCTION__); @@ -433,7 +431,7 @@ cc_int32 ccs_lock_state_remove (ccs_lock_state_t io_lock_state, for (i = 0; !err && i < lock_count; i++) { ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); - err = ccs_lock_is_for_client (lock, in_client_pipe, &found_lock); + err = ccs_lock_is_for_client_pipe (lock, in_client_pipe, &found_lock); if (!err && found_lock) { cci_debug_printf ("%s: Removing lock %p.", __FUNCTION__, lock); @@ -453,4 +451,33 @@ cc_int32 ccs_lock_state_remove (ccs_lock_state_t io_lock_state, return cci_check_error (err); } - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_state_invalidate_lock (ccs_lock_state_t io_lock_state, + ccs_lock_t in_lock) +{ + cc_int32 err = ccNoError; + + if (!io_lock_state) { err = ccErrBadParam; } + + if (!err) { + cc_uint64 i; + cc_uint64 count = ccs_lock_array_count (io_lock_state->locks); + + for (i = 0; !err && i < count; i++) { + ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); + + if (lock == in_lock) { + err = ccs_lock_status_remove_lock (io_lock_state, i); + + if (!err) { + err = ccs_lock_status_try_to_grant_pending_locks (io_lock_state); + break; + } + } + } + } + + return cci_check_error (err); +} diff --git a/src/ccapi/server/ccs_lock_state.h b/src/ccapi/server/ccs_lock_state.h index 3675c9f39..715c975b3 100644 --- a/src/ccapi/server/ccs_lock_state.h +++ b/src/ccapi/server/ccs_lock_state.h @@ -46,4 +46,7 @@ cc_int32 ccs_lock_state_add (ccs_lock_state_t io_lock_state, cc_int32 ccs_lock_state_remove (ccs_lock_state_t io_lock_state, ccs_pipe_t in_client_pipe); +cc_int32 ccs_lock_state_invalidate_lock (ccs_lock_state_t io_lock_state, + ccs_lock_t in_lock); + #endif /* CCS_LOCK_STATE_H */ diff --git a/src/ccapi/server/ccs_lockref.c b/src/ccapi/server/ccs_lockref.c new file mode 100644 index 000000000..78f80ae5d --- /dev/null +++ b/src/ccapi/server/ccs_lockref.c @@ -0,0 +1,121 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +struct ccs_lockref_d { + ccs_client_t client_owner; + ccs_lock_t lock; +}; + +struct ccs_lockref_d ccs_lockref_initializer = { NULL, NULL }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lockref_new (ccs_lockref_t *out_lockref, + ccs_client_t in_client_owner, + ccs_lock_t in_lock) +{ + cc_int32 err = ccNoError; + ccs_lockref_t lockref = NULL; + + if (!out_lockref ) { err = cci_check_error (ccErrBadParam); } + if (!in_client_owner) { err = cci_check_error (ccErrBadParam); } + if (!in_lock ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + lockref = malloc (sizeof (*lockref)); + if (lockref) { + *lockref = ccs_lockref_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + lockref->client_owner = in_client_owner; + lockref->lock = in_lock; + + *out_lockref = lockref; + lockref = NULL; + } + + ccs_lockref_release (lockref); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lockref_release (ccs_lockref_t io_lockref) +{ + cc_int32 err = ccNoError; + + if (!io_lockref) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (io_lockref->lock) { + ccs_lock_invalidate (io_lockref->lock); + } + free (io_lockref); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lockref_invalidate (ccs_lockref_t io_lockref) +{ + cc_int32 err = ccNoError; + + if (!io_lockref) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + io_lockref->lock = NULL; /* so we don't loop */ + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lockref_is_for_lock (ccs_lockref_t in_lockref, + ccs_lock_t in_lock, + cc_uint32 *out_is_for_lock) +{ + cc_int32 err = ccNoError; + + if (!in_lockref ) { err = cci_check_error (ccErrBadParam); } + if (!in_lock ) { err = cci_check_error (ccErrBadParam); } + if (!out_is_for_lock) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_is_for_lock = (in_lockref->lock == in_lock); + } + + return cci_check_error (err); +} diff --git a/src/ccapi/server/ccs_lockref.h b/src/ccapi/server/ccs_lockref.h new file mode 100644 index 000000000..2ed09a726 --- /dev/null +++ b/src/ccapi/server/ccs_lockref.h @@ -0,0 +1,44 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_LOCK_REFERENCE_H +#define CCS_LOCK_REFERENCE_H + +#include "ccs_types.h" + +cc_int32 ccs_lockref_new (ccs_lockref_t *out_lockref, + ccs_client_t in_client_owner, + ccs_lock_t in_lock); + +cc_int32 ccs_lockref_release (ccs_lockref_t io_lockref); + +cc_int32 ccs_lockref_invalidate (ccs_lockref_t io_lockref); + +cc_int32 ccs_lockref_is_for_lock (ccs_lockref_t in_lockref, + ccs_lock_t in_lock, + cc_uint32 *out_is_for_lock); + +#endif /* CCS_LOCK_REFERENCE_H */ diff --git a/src/ccapi/server/ccs_os_pipe.h b/src/ccapi/server/ccs_os_pipe.h index 049ce22fe..fd17828e5 100644 --- a/src/ccapi/server/ccs_os_pipe.h +++ b/src/ccapi/server/ccs_os_pipe.h @@ -29,16 +29,7 @@ #include "ccs_types.h" -cc_int32 ccs_os_pipe_copy (ccs_os_pipe_t *out_pipe, - ccs_os_pipe_t in_pipe); - -cc_int32 ccs_os_pipe_release (ccs_os_pipe_t io_pipe); - -cc_int32 ccs_os_pipe_compare (ccs_os_pipe_t in_pipe, - ccs_os_pipe_t in_compare_to_pipe, - cc_uint32 *out_equal); - -cc_int32 ccs_os_pipe_valid (ccs_os_pipe_t in_pipe); +cc_int32 ccs_os_pipe_valid (ccs_pipe_t in_pipe); #endif /* CCS_OS_PIPE_H */ diff --git a/src/ccapi/server/ccs_os_server.h b/src/ccapi/server/ccs_os_server.h index 557ad5905..c447ae4d0 100644 --- a/src/ccapi/server/ccs_os_server.h +++ b/src/ccapi/server/ccs_os_server.h @@ -29,6 +29,12 @@ #include "ccs_types.h" +cc_int32 ccs_os_server_initialize (int argc, const char *argv[]); + +cc_int32 ccs_os_server_cleanup (int argc, const char *argv[]); + +cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]); + cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_reply_pipe, cci_stream_t in_reply_stream); diff --git a/src/ccapi/server/ccs_pipe.c b/src/ccapi/server/ccs_pipe.c index 2b33f92a0..a7a547f17 100644 --- a/src/ccapi/server/ccs_pipe.c +++ b/src/ccapi/server/ccs_pipe.c @@ -27,137 +27,9 @@ #include "ccs_common.h" #include "ccs_os_pipe.h" -struct ccs_pipe_d { - ccs_os_pipe_t os_pipe; -}; - -struct ccs_pipe_d ccs_pipe_initializer = { CCS_OS_PIPE_NULL }; - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_pipe_new (ccs_pipe_t *out_pipe, - ccs_os_pipe_t in_os_pipe) -{ - cc_int32 err = ccNoError; - ccs_pipe_t new_pipe = NULL; - - if (!out_pipe ) { err = cci_check_error (ccErrBadParam); } - if (!ccs_os_pipe_valid (in_os_pipe)) { err = cci_check_error (ccErrBadParam); } - - if (!err) { - new_pipe = malloc (sizeof (*new_pipe)); - if (new_pipe) { - *new_pipe = ccs_pipe_initializer; - } else { - err = cci_check_error (ccErrNoMem); - } - } - - if (!err) { - err = ccs_os_pipe_copy (&new_pipe->os_pipe, in_os_pipe); - } - - if (!err) { - *out_pipe = new_pipe; - new_pipe = NULL; - } - - ccs_pipe_release (new_pipe); - return cci_check_error (err); -} - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_pipe_release (ccs_pipe_t io_pipe) -{ - cc_int32 err = ccNoError; - - if (!io_pipe) { err = ccErrBadParam; } - - if (!err) { - ccs_os_pipe_release (io_pipe->os_pipe); - free (io_pipe); - } - - return cci_check_error (err); -} - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_pipe_copy (ccs_pipe_t *out_pipe, - ccs_pipe_t in_pipe) -{ - cc_int32 err = ccNoError; - - if (!out_pipe) { err = cci_check_error (ccErrBadParam); } - if (!in_pipe ) { err = cci_check_error (ccErrBadParam); } - - if (!err) { - err = ccs_pipe_new (out_pipe, in_pipe->os_pipe); - } - - return cci_check_error (err); -} - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_pipe_compare (ccs_pipe_t in_pipe, - ccs_pipe_t in_compare_to_pipe, - cc_uint32 *out_equal) -{ - cc_int32 err = ccNoError; - - if (!in_pipe ) { err = cci_check_error (ccErrBadParam); } - if (!in_compare_to_pipe) { err = cci_check_error (ccErrBadParam); } - if (!out_equal ) { err = cci_check_error (ccErrBadParam); } - - if (!err) { - err = ccs_os_pipe_compare (in_pipe->os_pipe, - in_compare_to_pipe->os_pipe, - out_equal); - } - - return cci_check_error (err); -} - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_pipe_compare_to_os_pipe (ccs_pipe_t in_pipe, - ccs_os_pipe_t in_compare_to_os_pipe, - cc_uint32 *out_equal) -{ - cc_int32 err = ccNoError; - - if (in_pipe) { err = cci_check_error (ccErrBadParam); } - - if (!err) { - err = ccs_os_pipe_compare (in_pipe->os_pipe, - in_compare_to_os_pipe, - out_equal); - } - - return cci_check_error (err); -} - /* ------------------------------------------------------------------------ */ cc_int32 ccs_pipe_valid (ccs_pipe_t in_pipe) { - if (in_pipe) { - return ccs_os_pipe_valid (in_pipe->os_pipe); - } else { - return 0; - } -} - - -/* ------------------------------------------------------------------------ */ - -ccs_os_pipe_t ccs_pipe_os (ccs_pipe_t in_pipe) -{ - if (in_pipe) { - return in_pipe->os_pipe; - } else { - return CCS_OS_PIPE_NULL; - } + return ccs_os_pipe_valid (in_pipe); } diff --git a/src/ccapi/server/ccs_pipe.h b/src/ccapi/server/ccs_pipe.h index 3f736fc01..d124a9049 100644 --- a/src/ccapi/server/ccs_pipe.h +++ b/src/ccapi/server/ccs_pipe.h @@ -29,24 +29,6 @@ #include "ccs_types.h" -cc_int32 ccs_pipe_new (ccs_pipe_t *out_pipe, - ccs_os_pipe_t in_os_pipe); - -cc_int32 ccs_pipe_copy (ccs_pipe_t *out_pipe, - ccs_pipe_t in_pipe); - -cc_int32 ccs_pipe_release (ccs_pipe_t io_pipe); - -cc_int32 ccs_pipe_compare (ccs_pipe_t in_pipe, - ccs_pipe_t in_compare_to_pipe, - cc_uint32 *out_equal); - -cc_int32 ccs_pipe_compare_to_os_pipe (ccs_pipe_t in_pipe, - ccs_os_pipe_t in_compare_to_os_pipe, - cc_uint32 *out_equal); - cc_int32 ccs_pipe_valid (ccs_pipe_t in_pipe); -ccs_os_pipe_t ccs_pipe_os (ccs_pipe_t in_pipe); - #endif /* CCS_PIPE_H */ diff --git a/src/ccapi/server/ccs_server.c b/src/ccapi/server/ccs_server.c index 6f8fffe65..2a4cb0f7b 100644 --- a/src/ccapi/server/ccs_server.c +++ b/src/ccapi/server/ccs_server.c @@ -31,14 +31,18 @@ cci_uuid_string_t g_server_id = NULL; ccs_cache_collection_t g_cache_collection = NULL; -ccs_pipe_array_t g_client_pipe_array = NULL; +ccs_client_array_t g_client_array = NULL; /* ------------------------------------------------------------------------ */ - cc_int32 ccs_server_initialize (void) +int main (int argc, const char *argv[]) { - cc_int32 err = ccNoError; - + cc_int32 err = 0; + + if (!err) { + err = ccs_os_server_initialize (argc, argv); + } + if (!err) { err = cci_identifier_new_uuid (&g_server_id); } @@ -48,25 +52,22 @@ ccs_pipe_array_t g_client_pipe_array = NULL; } if (!err) { - err = ccs_pipe_array_new (&g_client_pipe_array); + err = ccs_client_array_new (&g_client_array); } - return cci_check_error (err); -} - -/* ------------------------------------------------------------------------ */ - - cc_int32 ccs_server_cleanup (void) -{ - cc_int32 err = ccNoError; + if (!err) { + err = ccs_os_server_listen_loop (argc, argv); + } if (!err) { free (g_server_id); cci_check_error (ccs_cache_collection_release (g_cache_collection)); - cci_check_error (ccs_pipe_array_release (g_client_pipe_array)); + cci_check_error (ccs_client_array_release (g_client_array)); + + err = ccs_os_server_cleanup (argc, argv); } - return cci_check_error (err); + return cci_check_error (err) ? 1 : 0; } #pragma mark - @@ -83,20 +84,20 @@ cc_int32 ccs_server_new_identifier (cci_identifier_t *out_identifier) /* ------------------------------------------------------------------------ */ -cc_int32 ccs_server_add_client (ccs_os_pipe_t in_connection_os_pipe) +cc_int32 ccs_server_add_client (ccs_pipe_t in_connection_pipe) { cc_int32 err = ccNoError; - ccs_pipe_t connection_pipe = NULL; + ccs_client_t client = NULL; if (!err) { - err = ccs_pipe_new (&connection_pipe, in_connection_os_pipe); + err = ccs_client_new (&client, in_connection_pipe); } if (!err) { - cci_debug_printf ("%s: Adding client %p.", __FUNCTION__, connection_pipe); - err = ccs_pipe_array_insert (g_client_pipe_array, - connection_pipe, - ccs_pipe_array_count (g_client_pipe_array)); + cci_debug_printf ("%s: Adding client %p.", __FUNCTION__, client); + err = ccs_client_array_insert (g_client_array, + client, + ccs_client_array_count (g_client_array)); } return cci_check_error (err); @@ -104,23 +105,23 @@ cc_int32 ccs_server_add_client (ccs_os_pipe_t in_connection_os_pipe) /* ------------------------------------------------------------------------ */ -cc_int32 ccs_server_remove_client (ccs_os_pipe_t in_connection_os_pipe) +cc_int32 ccs_server_remove_client (ccs_pipe_t in_connection_pipe) { cc_int32 err = ccNoError; if (!err) { cc_uint64 i; - cc_uint64 count = ccs_pipe_array_count (g_client_pipe_array); + cc_uint64 count = ccs_client_array_count (g_client_array); cc_uint32 found = 0; for (i = 0; !err && i < count; i++) { - ccs_pipe_t client = ccs_pipe_array_object_at_index (g_client_pipe_array, i); + ccs_client_t client = ccs_client_array_object_at_index (g_client_array, i); - err = ccs_pipe_compare_to_os_pipe (client, in_connection_os_pipe, &found); + err = ccs_client_uses_pipe (client, in_connection_pipe, &found); if (!err && found) { cci_debug_printf ("%s: Removing client %p.", __FUNCTION__, client); - err = ccs_pipe_array_remove (g_client_pipe_array, i); + err = ccs_client_array_remove (g_client_array, i); break; } } @@ -134,6 +135,63 @@ cc_int32 ccs_server_remove_client (ccs_os_pipe_t in_connection_os_pipe) return cci_check_error (err); } +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_server_client_for_pipe (ccs_pipe_t in_client_pipe, + ccs_client_t *out_client) +{ + cc_int32 err = ccNoError; + ccs_client_t client_for_pipe = NULL; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!out_client ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cc_uint64 i; + cc_uint64 count = ccs_client_array_count (g_client_array); + + for (i = 0; !err && i < count; i++) { + ccs_client_t client = ccs_client_array_object_at_index (g_client_array, i); + cc_uint32 uses_pipe = 0; + + err = ccs_client_uses_pipe (client, in_client_pipe, &uses_pipe); + + if (!err && uses_pipe) { + client_for_pipe = client; + break; + } + } + } + + if (!err) { + *out_client = client_for_pipe; /* may be NULL if not found */ + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_server_client_is_valid (ccs_pipe_t in_client_pipe, + cc_uint32 *out_client_is_valid) +{ + cc_int32 err = ccNoError; + ccs_client_t client = NULL; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!out_client_is_valid ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_server_client_for_pipe (in_client_pipe, &client); + } + + if (!err) { + *out_client_is_valid = (client != NULL); + } + + return cci_check_error (err); +} + #pragma mark - /* ------------------------------------------------------------------------ */ diff --git a/src/ccapi/server/ccs_server.h b/src/ccapi/server/ccs_server.h index 713271072..670a74ee2 100644 --- a/src/ccapi/server/ccs_server.h +++ b/src/ccapi/server/ccs_server.h @@ -29,15 +29,17 @@ #include "ccs_types.h" -cc_int32 ccs_server_initialize (void); +cc_int32 ccs_server_new_identifier (cci_identifier_t *out_identifier); -cc_int32 ccs_server_cleanup (void); +cc_int32 ccs_server_add_client (ccs_pipe_t in_connection_pipe); -cc_int32 ccs_server_new_identifier (cci_identifier_t *out_identifier); +cc_int32 ccs_server_remove_client (ccs_pipe_t in_connection_pipe); -cc_int32 ccs_server_add_client (ccs_os_pipe_t in_connection_os_pipe); +cc_int32 ccs_server_client_for_pipe (ccs_pipe_t in_client_pipe, + ccs_client_t *out_client); -cc_int32 ccs_server_remove_client (ccs_os_pipe_t in_connection_os_pipe); +cc_int32 ccs_server_client_is_valid (ccs_pipe_t in_client_pipe, + cc_uint32 *out_client_is_valid); cc_int32 ccs_server_handle_request (ccs_pipe_t in_client_pipe, ccs_pipe_t in_reply_pipe, diff --git a/src/ccapi/server/ccs_types.h b/src/ccapi/server/ccs_types.h index f96e8d39d..67f9c89bd 100644 --- a/src/ccapi/server/ccs_types.h +++ b/src/ccapi/server/ccs_types.h @@ -31,7 +31,9 @@ struct cci_array_d; -typedef struct cci_array_d *ccs_pipe_array_t; +typedef struct cci_array_d *ccs_client_array_t; + +typedef struct cci_array_d *ccs_lockref_array_t; typedef struct cci_array_d *ccs_lock_array_t; @@ -41,19 +43,19 @@ typedef struct cci_array_d *ccs_lock_array_t; #if TARGET_OS_MAC #include -typedef mach_port_t ccs_os_pipe_t; /* Mach IPC port */ -#define CCS_OS_PIPE_NULL MACH_PORT_NULL +typedef mach_port_t ccs_pipe_t; /* Mach IPC port */ +#define CCS_PIPE_NULL MACH_PORT_NULL #else -typedef int ccs_os_pipe_t; /* Unix domain socket */ -#define CCS_OS_PIPE_NULL -1 +typedef int ccs_pipe_t; /* Unix domain socket */ +#define CCS_PIPE_NULL -1 #endif #pragma mark - -struct ccs_pipe_d; -typedef struct ccs_pipe_d *ccs_pipe_t; +struct ccs_lockref_d; +typedef struct ccs_lockref_d *ccs_lockref_t; struct ccs_list_d; struct ccs_list_iterator_d; diff --git a/src/ccapi/server/mac/ccs_os_pipe.c b/src/ccapi/server/mac/ccs_os_pipe.c index d22ffe353..0b5fa8952 100644 --- a/src/ccapi/server/mac/ccs_os_pipe.c +++ b/src/ccapi/server/mac/ccs_os_pipe.c @@ -28,51 +28,11 @@ #include "ccs_os_pipe.h" #include -/* On Mac OS X ccs_os_pipe_t is a mach_port_t */ +/* On Mac OS X ccs_pipe_t is a mach_port_t */ /* ------------------------------------------------------------------------ */ -cc_int32 ccs_os_pipe_copy (ccs_os_pipe_t *out_pipe, - ccs_os_pipe_t in_pipe) -{ - cc_int32 err = ccNoError; - - if (!out_pipe) { err = cci_check_error (ccErrBadParam); } - - if (!err) { - *out_pipe = in_pipe; - } - - return cci_check_error (err); -} - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_os_pipe_release (ccs_os_pipe_t io_pipe) -{ - return ccNoError; -} - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_os_pipe_compare (ccs_os_pipe_t in_pipe, - ccs_os_pipe_t in_compare_to_pipe, - cc_uint32 *out_equal) -{ - cc_int32 err = ccNoError; - - if (!out_equal) { err = cci_check_error (ccErrBadParam); } - - if (!err) { - *out_equal = (in_pipe == in_compare_to_pipe); - } - - return cci_check_error (err); -} - -/* ------------------------------------------------------------------------ */ - -cc_int32 ccs_os_pipe_valid (ccs_os_pipe_t in_pipe) +cc_int32 ccs_os_pipe_valid (ccs_pipe_t in_pipe) { return MACH_PORT_VALID (in_pipe); } diff --git a/src/ccapi/server/mac/main.c b/src/ccapi/server/mac/ccs_os_server.c similarity index 87% rename from src/ccapi/server/mac/main.c rename to src/ccapi/server/mac/ccs_os_server.c index 0753a240b..eefac4c8a 100644 --- a/src/ccapi/server/mac/main.c +++ b/src/ccapi/server/mac/ccs_os_server.c @@ -32,6 +32,7 @@ #include "cci_mig_reply.h" #include "ccs_os_server.h" + /* ------------------------------------------------------------------------ */ static boolean_t ccs_server_demux (mach_msg_header_t *request, @@ -45,7 +46,7 @@ static boolean_t ccs_server_demux (mach_msg_header_t *request, if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) { kern_return_t err = KERN_SUCCESS; - + err = ccs_server_remove_client (request->msgh_local_port); if (!err) { @@ -57,7 +58,7 @@ static boolean_t ccs_server_demux (mach_msg_header_t *request, if (!err) { handled = 1; /* was a port we are tracking */ } - + cci_check_error (err); } @@ -66,32 +67,6 @@ static boolean_t ccs_server_demux (mach_msg_header_t *request, /* ------------------------------------------------------------------------ */ -int main (int argc, const char *argv[]) -{ - cc_int32 err = 0; - - openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH); - syslog (LOG_INFO, "Starting up."); - - if (!err) { - err = ccs_server_initialize (); - } - - if (!err) { - err = kipc_server_run_server (ccs_server_demux); - } - - /* cleanup ccs resources */ - ccs_server_cleanup (); - - syslog (LOG_NOTICE, "Exiting: %s (%d)", kipc_error_string (err), err); - - /* exit */ - return err ? 1 : 0; -} - -/* ------------------------------------------------------------------------ */ - kern_return_t ccs_mipc_create_client_connection (mach_port_t in_server_port, mach_port_t *out_connection_port) { @@ -130,6 +105,85 @@ kern_return_t ccs_mipc_create_client_connection (mach_port_t in_server_port, /* ------------------------------------------------------------------------ */ +kern_return_t ccs_mipc_request (mach_port_t in_connection_port, + mach_port_t in_reply_port, + cci_mipc_inl_request_t in_inl_request, + mach_msg_type_number_t in_inl_requestCnt, + cci_mipc_ool_request_t in_ool_request, + mach_msg_type_number_t in_ool_requestCnt) +{ + kern_return_t err = KERN_SUCCESS; + cci_stream_t request_stream = NULL; + + if (!err) { + err = cci_stream_new (&request_stream); + } + + if (!err) { + if (in_inl_requestCnt) { + err = cci_stream_write (request_stream, in_inl_request, in_inl_requestCnt); + + } else if (in_ool_requestCnt) { + err = cci_stream_write (request_stream, in_ool_request, in_ool_requestCnt); + + } else { + err = cci_check_error (ccErrBadInternalMessage); + } + } + + if (!err) { + err = ccs_server_handle_request (in_connection_port, in_reply_port, request_stream); + } + + cci_stream_release (request_stream); + if (in_ool_requestCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_request, in_ool_requestCnt); } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_os_server_initialize (int argc, const char *argv[]) +{ + cc_int32 err = 0; + + openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH); + syslog (LOG_INFO, "Starting up."); + + syslog (LOG_NOTICE, "Exiting: %s (%d)", kipc_error_string (err), err); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_os_server_cleanup (int argc, const char *argv[]) +{ + cc_int32 err = 0; + + openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH); + syslog (LOG_INFO, "Starting up."); + + syslog (LOG_NOTICE, "Exiting: %s (%d)", kipc_error_string (err), err); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_os_server_listen_loop (int argc, const char *argv[]) +{ + /* Run the Mach IPC listen loop. + * This will call ccs_mipc_create_client_connection for new clients + * and ccs_mipc_request for existing clients */ + + return cci_check_error (kipc_server_run_server (ccs_server_demux)); +} + +/* ------------------------------------------------------------------------ */ + cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_reply_pipe, cci_stream_t in_reply_stream) { @@ -165,7 +219,7 @@ cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_reply_pipe, } if (!err) { - err = ccs_mipc_reply (ccs_pipe_os (in_reply_pipe), + err = ccs_mipc_reply (in_reply_pipe, inl_reply, inl_reply_length, ool_reply, ool_reply_length); } @@ -180,54 +234,3 @@ cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_reply_pipe, return cci_check_error (err); } - - -/* ------------------------------------------------------------------------ */ - -kern_return_t ccs_mipc_request (mach_port_t in_connection_port, - mach_port_t in_reply_port, - cci_mipc_inl_request_t in_inl_request, - mach_msg_type_number_t in_inl_requestCnt, - cci_mipc_ool_request_t in_ool_request, - mach_msg_type_number_t in_ool_requestCnt) -{ - kern_return_t err = KERN_SUCCESS; - cci_stream_t request_stream = NULL; - ccs_pipe_t connection_pipe = NULL; - ccs_pipe_t reply_pipe = NULL; - - if (!err) { - err = cci_stream_new (&request_stream); - } - - if (!err) { - if (in_inl_requestCnt) { - err = cci_stream_write (request_stream, in_inl_request, in_inl_requestCnt); - - } else if (in_ool_requestCnt) { - err = cci_stream_write (request_stream, in_ool_request, in_ool_requestCnt); - - } else { - err = cci_check_error (ccErrBadInternalMessage); - } - } - - if (!err) { - err = ccs_pipe_new (&connection_pipe, in_connection_port); - } - - if (!err) { - err = ccs_pipe_new (&reply_pipe, in_reply_port); - } - - if (!err) { - err = ccs_server_handle_request (connection_pipe, reply_pipe, request_stream); - } - - ccs_pipe_release (connection_pipe); - ccs_pipe_release (reply_pipe); - cci_stream_release (request_stream); - if (in_ool_requestCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_request, in_ool_requestCnt); } - - return cci_check_error (err); -} -- 2.26.2