summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libhurd-cap-server/ChangeLog18
-rw-r--r--libhurd-cap-server/cap-server.h56
-rw-r--r--libhurd-cap-server/class-create.c7
-rw-r--r--libhurd-cap-server/class-init.c19
-rw-r--r--libhurd-cap-server/obj-copy-out.c2
5 files changed, 64 insertions, 38 deletions
diff --git a/libhurd-cap-server/ChangeLog b/libhurd-cap-server/ChangeLog
index 62d7801..d0a951d 100644
--- a/libhurd-cap-server/ChangeLog
+++ b/libhurd-cap-server/ChangeLog
@@ -1,5 +1,23 @@
2004-11-30 Neal H. Walfield <neal@gnu.org>
+ * cap-server.h: Improve comments.
+ (hurd_cap_class_create_untyped): Tighten alignment restrictions:
+ ALIGNMENT must be a power of 2.
+ * class-init.c (hurd_cap_class_init_untyped): Calculate best
+ alignment.
+
+ * cap-server.h (hurd_cap_obj_get_size): Renamed to ...
+ (hurd_cap_obj_user_offset): ... this.
+ (hurd_cap_obj_to_user_untyped): Call hurd_cap_obj_user_offset, not
+ hurd_cap_obj_get_size.
+ (hurd_cap_obj_from_user_untyped): Likewise.
+ * class-init.c (hurd_cap_class_init_untyped): Likewise.
+
+ * class-create.c: Improve comments.
+ * obj-copy-out.c: Likewise.
+
+2004-11-30 Neal H. Walfield <neal@gnu.org>
+
* cap-server-intern.h (_hurd_cap_obj_drop): Reverse faulty logic.
2004-11-30 Neal H. Walfield <neal@gnu.org>
diff --git a/libhurd-cap-server/cap-server.h b/libhurd-cap-server/cap-server.h
index b85f3f1..3b3505d 100644
--- a/libhurd-cap-server/cap-server.h
+++ b/libhurd-cap-server/cap-server.h
@@ -219,19 +219,18 @@ struct hurd_cap_obj
/* The reference counter for this object. */
uatomic32_t refs;
- /* The state of this object. If this is _HURD_CAP_STATE_GREEN, you
- can use the capability object. Otherwise, you should refrain
- from using it. You can sleep on the obj_state_cond condition in
- the capability class until the state goes back to
- _HURD_CAP_STATE_GREEN again.
-
- If the state is _HURD_CAP_STATE_YELLOW, this means that there is
- some thread who wants the state to be _HURD_CAP_STATE_RED, and
- this thread canceled all other pending RPC threads on this
- object. If you are the last worker thread for this capability
- object (except for the thread waiting for the condition to become
- _HURD_CAP_STATE_RED), you have to broadcast the obj_state_cond
- condition.
+ /* The state of the capability object.
+
+ If STATE is _HURD_CAP_STATE_GREEN, you can use the capability
+ object. Otherwise, you must wait on the condition
+ CAP_CLASS->OBJ_COND for it return to _HURD_CAP_STATE_GREEN.
+
+ If the state is _HURD_CAP_STATE_YELLOW, a thread wants the state
+ to be _HURD_CAP_STATE_RED (and it has canceled all other pending
+ RPC threads on this object). The last worker thread for this
+ capability object (other than the thread waiting for the
+ condition to become _HURD_CAP_STATE_RED) must broadcast the
+ obj_state_cond condition.
Every worker thread that blocks on the capability object state
until it reverts to _HURD_CAP_STATE_GREEN must perform a
@@ -259,7 +258,7 @@ struct hurd_cap_obj
/* Operations on capability classes. */
/* Create a new capability class for objects with the size SIZE and
- alignment requirement ALIGNMENT.
+ alignment requirement ALIGNMENT (which must be a power of 2).
The callback OBJ_INIT is used whenever a capability object in this
class is created. The callback OBJ_REINIT is used whenever a
@@ -333,19 +332,21 @@ error_t hurd_cap_class_alloc (hurd_cap_class_t cap_class,
hurd_cap_obj_t *r_obj);
-/* Get the size of the header, given the alignment requirement
- ALIGNMENT of the user object following it. */
+/* Get the offset of the user object following a capability.
+ ALIGNMENT is the alignment requirements of the user object as
+ supplied to hurd_cap_class_init, hurd_cap_class_init_untyped,
+ hurd_cap_class_create or hurd_cap_class_create_untyped. */
static inline size_t
__attribute__((__always_inline__))
-hurd_cap_obj_get_size (size_t alignment)
+hurd_cap_obj_user_offset (size_t alignment)
{
- size_t obj_size = sizeof (struct hurd_cap_obj);
+ size_t offset = sizeof (struct hurd_cap_obj);
size_t rest = sizeof (struct hurd_cap_obj) % alignment;
if (rest)
- obj_size += alignment - rest;
+ offset += alignment - rest;
- return obj_size;
+ return offset;
}
@@ -360,7 +361,7 @@ hurd_cap_obj_to_user_untyped (hurd_cap_obj_t obj, size_t alignment)
{
uintptr_t obj_addr = (uintptr_t) obj;
- obj_addr += hurd_cap_obj_get_size (alignment);
+ obj_addr += hurd_cap_obj_user_offset (alignment);
return (void *) obj_addr;
}
@@ -380,7 +381,7 @@ hurd_cap_obj_from_user_untyped (void *obj, size_t alignment)
{
uintptr_t obj_addr = (uintptr_t) obj;
- obj_addr -= hurd_cap_obj_get_size (alignment);
+ obj_addr -= hurd_cap_obj_user_offset (alignment);
return (hurd_cap_obj_t) obj_addr;
}
@@ -409,7 +410,6 @@ hurd_cap_obj_lock (hurd_cap_obj_t obj)
pthread_mutex_lock (&obj->lock);
}
-
/* Unlock the object OBJ, which must be locked. */
static inline void
hurd_cap_obj_unlock (hurd_cap_obj_t obj)
@@ -418,7 +418,7 @@ hurd_cap_obj_unlock (hurd_cap_obj_t obj)
}
-/* Add a reference for the capability object OBJ. */
+/* Add a reference to the capability object OBJ. */
static inline void
hurd_cap_obj_ref (hurd_cap_obj_t obj)
{
@@ -426,9 +426,11 @@ hurd_cap_obj_ref (hurd_cap_obj_t obj)
}
-/* Remove one reference for the capability object OBJ. Note that the
- caller must have at least two references for this capability object
- when using this function. To release the last reference,
+/* Remove one reference for the capability object OBJ, which must be
+ locked. Note that the caller must have at least two references for
+ this capability object when using this function. If this reference
+ is potentially the last reference (i.e. the caller does not hold
+ either directly or indirectly another reference to OBJ),
hurd_cap_obj_drop must be used instead. */
static inline void
hurd_cap_obj_rele (hurd_cap_obj_t obj)
diff --git a/libhurd-cap-server/class-create.c b/libhurd-cap-server/class-create.c
index e60deff..2f4c16a 100644
--- a/libhurd-cap-server/class-create.c
+++ b/libhurd-cap-server/class-create.c
@@ -29,9 +29,10 @@
#include <hurd/cap-server.h>
-/* Create a new capability class for objects with the size SIZE,
- including the struct hurd_cap_obj, which has to be placed at the
- beginning of each capability object.
+/* Create a new capability class for objects allocating SIZE bytes for
+ the user object with alignment ALIGNMENT (i.e. size does NOT
+ include the struct hurd_cap_obj which is placed at the beginning of
+ each capability object).
The callback OBJ_INIT is used whenever a capability object in this
class is created. The callback OBJ_REINIT is used whenever a
diff --git a/libhurd-cap-server/class-init.c b/libhurd-cap-server/class-init.c
index 9c7d185..cdbb7db 100644
--- a/libhurd-cap-server/class-init.c
+++ b/libhurd-cap-server/class-init.c
@@ -97,11 +97,17 @@ hurd_cap_class_init_untyped (hurd_cap_class_t cap_class,
{
error_t err;
- size += hurd_cap_obj_get_size (alignment);
+ /* The alignment requirements must be a power of 2. */
+ assert ((alignment & (alignment - 1)) == 0
+ || ! __func__ ": requested alignment not a power of 2");
- /* FIXME: Find the smallest possible alignment common to the user
- object and a struct hurd_cap_obj. */
- assert (alignment >= __alignof__(struct hurd_cap_obj));
+ /* Find the smallest alignment requirement common to the user object
+ and a struct hurd_cap_obj. Since both are required to be a power
+ of 2, we need simply take the larger one. */
+ if (alignment < __alignof__(struct hurd_cap_obj))
+ alignment = __alignof__(struct hurd_cap_obj);
+
+ size += hurd_cap_obj_user_offset (alignment);
/* Capability object management. */
@@ -139,9 +145,8 @@ hurd_cap_class_init_untyped (hurd_cap_class_t cap_class,
if (err)
goto err_cond;
- /* The cond_waiter member doesn't need to be initialized. It is set
- whenever the state changes to _HURD_CAP_STATE_YELLOW by the
- inhibitor. */
+ /* The cond_waiter member doesn't need to be initialized. It is
+ only valid when CAP_CLASS->STATE is _HURD_CAP_STATE_YELLOW. */
cap_class->pending_rpcs = NULL;
diff --git a/libhurd-cap-server/obj-copy-out.c b/libhurd-cap-server/obj-copy-out.c
index 6bac033..070b7e0 100644
--- a/libhurd-cap-server/obj-copy-out.c
+++ b/libhurd-cap-server/obj-copy-out.c
@@ -83,7 +83,7 @@ _hurd_cap_obj_copy_out (hurd_cap_obj_t obj, hurd_cap_bucket_t bucket,
return 0;
}
- /* Add the entry to the caps table of the client. */
+ /* Add the entry to the cap table of the client. */
err = hurd_table_enter (&client->caps, &entry, &entry->id);
if (err)
{