aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexandra Ellwood <lxs@mit.edu>2007-06-12 21:07:16 +0000
committerAlexandra Ellwood <lxs@mit.edu>2007-06-12 21:07:16 +0000
commit05b0fe74bb6eb10a49333d42f9f1677235863f85 (patch)
treebbf3ca5514c49c0ac7d4f70073cb3208607cc05d /src
parentfd7e3b884d0fa19a4d9b1f1965e656b62beb7351 (diff)
downloadkrb5-05b0fe74bb6eb10a49333d42f9f1677235863f85.zip
krb5-05b0fe74bb6eb10a49333d42f9f1677235863f85.tar.gz
krb5-05b0fe74bb6eb10a49333d42f9f1677235863f85.tar.bz2
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
Diffstat (limited to 'src')
-rw-r--r--src/ccapi/server/ccs_array.c83
-rw-r--r--src/ccapi/server/ccs_array.h40
-rw-r--r--src/ccapi/server/ccs_client.c169
-rw-r--r--src/ccapi/server/ccs_client.h47
-rw-r--r--src/ccapi/server/ccs_common.h2
-rw-r--r--src/ccapi/server/ccs_lock.c85
-rw-r--r--src/ccapi/server/ccs_lock.h23
-rw-r--r--src/ccapi/server/ccs_lock_state.c57
-rw-r--r--src/ccapi/server/ccs_lock_state.h3
-rw-r--r--src/ccapi/server/ccs_lockref.c121
-rw-r--r--src/ccapi/server/ccs_lockref.h44
-rw-r--r--src/ccapi/server/ccs_os_pipe.h11
-rw-r--r--src/ccapi/server/ccs_os_server.h6
-rw-r--r--src/ccapi/server/ccs_pipe.c130
-rw-r--r--src/ccapi/server/ccs_pipe.h18
-rw-r--r--src/ccapi/server/ccs_server.c112
-rw-r--r--src/ccapi/server/ccs_server.h12
-rw-r--r--src/ccapi/server/ccs_types.h16
-rw-r--r--src/ccapi/server/mac/ccs_os_pipe.c44
-rw-r--r--src/ccapi/server/mac/ccs_os_server.c (renamed from src/ccapi/server/mac/main.c)163
20 files changed, 793 insertions, 393 deletions
diff --git a/src/ccapi/server/ccs_array.c b/src/ccapi/server/ccs_array.c
index 6826933..7683c94 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 6f896cb..05bcbdf 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 0000000..f23792a
--- /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 0000000..3b62682
--- /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 f035780..2013c9e 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 939da5e..3fa761e 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 197f5d5..bed0a9e 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 c90311f..b8dc5de 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 3675c9f..715c975 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 0000000..78f80ae
--- /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 0000000..2ed09a7
--- /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 049ce22..fd17828 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 557ad59..c447ae4 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 2b33f92..a7a547f 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 3f736fc..d124a90 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 6f8fffe..2a4cb0f 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 7132710..670a74e 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 f96e8d3..67f9c89 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 <mach/mach_types.h>
-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 d22ffe3..0b5fa89 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 <mach/port.h>
-/* 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
index 0753a24..eefac4c 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);
-}