[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Every Hurd program accepts the following optional arguments:
The rest of this chapter provides a programmer's introduction to the Hurd. If you are not a programmer, then this chapter will not make much sense to you... you should consider skipping to descriptions of specific Hurd programs (see section 1.1 Audience).
The Hurd distribution includes many libraries in order to provide a useful set of tools for writing Hurd utilities and servers. Several of these libraries are useful not only for the Hurd, but also for writing microkernel-based programs in general. These fundamental libraries are not difficult to understand, and they are a good starting point, because the rest of the Hurd relies upon them quite heavily.
3.1 Threads Library | Every Hurd server and library is multithreaded. | |
3.2 Ports Library | Managing server port receive rights. | |
3.3 Integer Hash Library | Integer-keyed hash tables. | |
3.4 Misc Library | Things that soon will be in the GNU C library. | |
3.5 Bug Address Library | Where to report Hurd bugs. |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
All Hurd servers and libraries are aggressively multithreaded in order
to take full advantage of any multiprocessing capabilities provided by
the microkernel and the underlying hardware. The Hurd threads library,
libthreads
, contains the default Hurd thread implementation, which
is declared in <cthreads.h>
.
Currently (April 1998), the Hurd uses cthreads, which have already been documented thoroughly by CMU. Eventually, it will be migrated to use POSIX pthreads, which are documented in a lot of places.
Every single library in the Hurd distribution (including the GNU C library) is completely thread-safe, and the Hurd servers themselves are aggressively multithreaded.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Ports are communication channels that are held by the kernel.
A port has separate send rights and receive rights, which may be transferred from task to task via the kernel. Port rights are similar to Unix file descriptors: they are per-task integers which are used to identify ports when making kernel calls. Send rights are required in order to send an RPC request down a port, and receive rights are required to serve the RPC request. Receive rights may be aggregated into a single portset, which serve as useful organizational units.
In a single-threaded RPC client, managing and categorizing ports is not a difficult process. However, in a complex multithreaded server, it is useful to have a more abstract interface to managing portsets, as well as maintaining server metadata.
The Hurd ports library, libports
, fills that need. The
libports
functions are declared in <hurd/ports.h>
.
3.2.1 Buckets and Classes | Basic units of port organization. | |
3.2.2 Port Rights | Moving port rights to and from libports . | |
3.2.3 Port Metadata | Managing port-related information. | |
3.2.4 Port References | Guarding against leaks and lossage. | |
3.2.5 RPC Management | Locking and interrupting RPC operations. |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The libports
bucket is simply a port set, with some
metadata and a lock. All of the libports
functions operate on
buckets.
A port class is a collection of individual ports, which can be manipulated conveniently, and have enforced deallocation routines. Buckets and classes are entirely orthogonal: there is no requirement that all the ports in a class be in the same bucket, nor is there a requirement that all the ports in a bucket be in the same class.
Once you have created at least one bucket and class, you may create new ports, and store them in those buckets. There are a few different functions for port creation, depending on your application's requirements:
ports_create_port
, except don't actually put the port
into the portset underlying bucket. This is intended to be used
for cases where the port right must be given out before the port is
fully initialized; with this call you are guaranteed that no RPC service
will occur on the port until you have finished initializing it and
installed it into the portset yourself.
ports_create_port
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following functions move port receive rights to and from the port structure:
ports_reallocate_port
and
ports_reallocate_from_external
may not be used.
ports_destroy_right
,
except that the receive right itself is not affected. Note that in
multi-threaded servers, messages might already have been dequeued for
this port before it gets removed from the portset; such messages will
get EOPNOTSUPP
errors.
ports_destroy_right
were called) and topt's old right is
destroyed (as if ports_reallocate_from_external
were called).
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It is important to point out that the port argument to each of
the libports
functions is a void *
and not a struct
port_info *
. This is done so that you may add arbitrary
meta-information to your libports
-managed ports. Simply define
your own structure whose first element is a struct port_info
, and
then you can use pointers to these structures as the port argument
to any libports
function.
The following functions are useful for maintaining metadata that is stored in your own custom ports structure:
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
These functions maintain references to ports so that the port
information structures may be freed if and only if they are no longer
needed. It is your responsibility to tell libports
when
references to ports change.
ports_count_class
) to
continue.
ports_count_bucket
) to
continue.
Weak references are not often used, as they are the same as hard references for port classes where dropweak_routine is null. See section 3.2.1 Buckets and Classes.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The rest of the libports
functions are dedicated to controlling
RPC operations. These functions help you do all the locking and thread
cancellations that are required in order to build robust servers.
EDIED
; otherwise we return zero.
ports_begin_rpc
.
ports_inhibit_port_rpcs
, but affects all ports in
class.
ports_inhibit_port_rpcs
, but affects all ports in
bucket.
ports_inhibit_port_rpcs
, but affects all ports
whatsoever.
ports_inhibit_port_rpcs
for this
port, allowing blocked RPCs to continue.
ports_inhibit_class_rpcs
for
class.
ports_inhibit_bucket_rpcs
for
bucket.
ports_inhibit_all_rpcs
.
thread_cancel
) any RPCs in progress on port.
ports_interrupt_rpcs
, return nonzero and clear the interrupted
flag.
hurd_cancel
to be called on rpc's thread if
object gets notified that any of the things in what have
happened to port. rpc should be an RPC on object.
hurd_cancel
to be called on the current thread, which
should be an RPC on object, if port gets notified with the
condition what.
ports_interrupt_self_on_notification
with
what set to MACH_NOTIFY_DEAD_NAME
.
ports_interrupt_notified_rpcs
with what set
to MACH_NOTIFY_DEAD_NAME
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
libihash
provides integer-keyed hash tables, for arbitrary
element data types. Such hash tables are frequently used when
implementing sparse arrays or buffer caches.
The following functions are declared in <hurd/ihash.h>
:
ENOMEM
is returned, otherwise zero.
void
**
, and will be filled with a pointer that may be used as an argument
to ihash_locp_remove
. The variable pointed to by locp may
be overwritten sometime between this call and when the element is
deleted, so you cannot stash its value elsewhere and hope to use the
stashed value with ihash_locp_remove
. If a memory allocation
error occurs, ENOMEM
is returned, otherwise zero.
ihash_iterate
returns that value, otherwise it (eventually)
returns 0.
ihash_add
. This call
should be faster than ihash_remove
. ht can be null, in
which case the call still succeeds, but no cleanup is done.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The GNU C library is constantly developing to meet the needs of the Hurd. However, because the C library needs to be very stable, it is irresponsible to add new functions to it without carefully specifying their interface, and testing them thoroughly.
The Hurd distribution includes a library called
libshouldbeinlibc
, which serves as a proving ground for additions
to the GNU C library. This library is in flux, as some functions are
added to it by the Hurd developers and others are moved to the official
C library.
These functions aren't currently documented (other than in their header files), but complete documentation will be added to @xref{Top, The GNU C Library Reference Manual,, libc}, when these functions become part of the GNU C library.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
libhurdbugaddr
exists only to define a single variable:
argp_program_bug_address
is the default Hurd bug-reporting e-mail
address, bug-hurd@gnu.org. This address is displayed to the
user when any of the standard Hurd servers and utilities are invoked
using the `--help' option.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |