DOOR_CREATE(3C) Standard C Library Functions DOOR_CREATE(3C)

door_create, door_xcreatecreate a door descriptor

Standard C Library (libc, -lc)

#include <door.h>

int
door_create(door_server_procedure_t *server_procedure, void *cookie, uint_t attributes);

int
door_xcreate(door_server_procedure_t *server_procedure, void *cookie, uint_t attributes, door_xcreate_server_func_t *thr_create_func, door_xcreate_thrsetup_func_t *thr_setup_func, void *crcookie, int nthread);

The () function creates a door descriptor that describes the procedure specified by the function server_procedure, which must be of the door_server_procedure_t type:

typedef void door_server_procedure_t(void *cookie, char *argp,
    size_t arg_size, door_desc_t *dp, uint_t n_desc);

The data item, cookie, is associated with the door descriptor, and is passed as an argument to the invoked function server_procedure during door_call(3C) invocations. Other arguments passed to server_procedure from an associated () are placed on the stack and include argp and dp. The argp argument points to arg_size bytes of data and the dp argument points to n_desc door_desc_t structures. The attributes argument specifies attributes associated with the newly created door. Valid values for attributes are constructed by OR-ing one or more of the following values:

Delivers a special invocation on the door when the number of descriptors that refer to this door drops to one. In order to trigger this condition, more than one descriptor must have referred to this door at some time. DOOR_UNREF_DATA designates an unreferenced invocation, as the argp argument passed to server_procedure. In the case of an unreferenced invocation, the values for arg_size, dp and n_desc are . Only one unreferenced invocation is delivered on behalf of a door.
Similar to DOOR_UNREF, except multiple unreferenced invocations can be delivered on the same door if the number of descriptors referring to the door drops to one more than once. Since an additional reference may have been passed by the time an unreferenced invocation arrives, the DOOR_IS_UNREF attribute returned by the door_info(3C) call can be used to determine if the door is still unreferenced.
Maintains a separate pool of server threads on behalf of the door. Server threads are associated with a door's private server pool using door_bind(3C).
Any attempt to call door_call(3C) on this door with argument descriptors will fail with ENOTSUP. When this flag is set, the door's server procedure will always be invoked with an n_desc argument of 0.
Clients which abort calls to door_call() on this door will not cause the cancellation of the server thread handling the request. See cancellation(7).

The descriptor returned from () and door_xcreate() will be marked as close on exec (FD_CLOEXEC). Information about a door is available for all clients of a door using (). Applications concerned with security should not place secure information in door data that is accessible by door_info(). In particular, secure data should not be stored in the data item cookie.

By default, additional threads are created as needed to handle concurrent () invocations of doors created with door_create(). See door_server_create(3C) for information on how to change this behavior. The server threads of doors created with door_xcreate() are managed as described below.

A process can advertise a door in the file system name space using fattach(3C).

After creation, door_setparam(3C) can be used to set limits on the amount of data and descriptors clients can send over the door.

The () function creates a door as door_create() does, but with a private pool of server threads whose creation and attributes are under the control of the application. In addition to the attributes described above, attributes may include the following value, which is not supported by door_create():

The thr_create_func function is called to create the initial pool of server threads only. It is not called again when the pool is found to be depleted.

The thr_create_func and thr_setup_func arguments are pointers to functions of the following types:

typedef int door_xcreate_server_func_t(door_info_t *dip,
    void *(*startf)(void *), void *startfarg, void *crcookie);

typedef void door_xcreate_thrsetup_func_t(void *crcookie);

The thr_create_func function is called once for each server thread that is required, with dip pointing to a door_info_t that identifies the door, and with the crcookie argument that was passed to (). It must attempt to create one new thread that runs the start function startf with the argument startfarg, passing both to thr_create(3C) or pthread_create(3C) unmodified. The new thread must be created detached, and may otherwise be configured as the application wishes, for example with a different stack size or signal mask. The thr_create_func function must return 1 on success, -1 if thread creation failed, and 0 if no more server threads should be created at this time.

During the call to (), thr_create_func is called nthread times to create the door's initial pool of server threads. nthread must be at least 1. All nthread threads must be created successfully and bind to the door's private pool, otherwise door_xcreate() fails and any threads that were created exit. Unless the door was created with DOOR_NO_DEPLETION_CB, thr_create_func is subsequently called again each time a door invocation finds all of the threads in the pool busy, giving the application the opportunity to grow the pool. These depletion callbacks can be distinguished from initial pool creation by the presence of DOOR_DEPLETION_CB in the di_attributes member of the door_info_t to which dip points. Returning 0 from thr_create_func during a depletion callback is not an error, and can be used to limit the size of the pool. A door invocation that finds no available server thread waits in the kernel until one becomes free.

If thr_setup_func is not NULL, each new server thread calls it with crcookie before binding to the door's private pool. This can be used to perform once-only thread configuration such as setting up thread-specific data or blocking signals. If thr_setup_func is NULL, the thread has POSIX thread cancellation disabled, as for threads created by the default server thread creation function. The thread then binds to the door's private pool and makes itself available to service invocations. The application does not call door_bind(3C) or door_return(3C) itself.

Upon successful completion, door_create() and door_xcreate() return a non-negative value. Otherwise, they return -1 and set errno to indicate the error. If door_xcreate() fails, no door is created and no new server threads remain.

Example 1 Create a door and use fattach() to advertise the door in the file system namespace.

The following example creates a door and uses fattach() to advertise the door in the file system namespace.

void
server(void *cookie, char *argp, size_t arg_size, door_desc_t *dp,
    uint_t n_desc)
{
    door_return(NULL, 0, NULL, 0);
    /* NOTREACHED */
}

int
main(int argc, char *argv[])
{
    int did;
    struct stat buf;

    if ((did = door_create(server, 0, 0)) < 0) {
        perror("door_create");
        exit(1);
    }

    /* make sure file system location exists */
    if (stat("/tmp/door", &buf) < 0) {
        int newfd;
        if ((newfd = creat("/tmp/door", 0444)) < 0) {
            perror("creat");
            exit(1);
        }
        (void) close(newfd);
    }

    /* make sure nothing else is attached */
    (void) fdetach("/tmp/door");

    /* attach to file system */
    if (fattach(did, "/tmp/door") < 0) {
        perror("fattach");
        exit(2);
    }
    [...]
}

Example 2 Create a door with a bounded pool of server threads.

The following example uses door_xcreate() to create a door that is serviced by a fixed pool of four threads with a smaller stack size than the default. Since the door is created with DOOR_NO_DEPLETION_CB, the pool never grows beyond its initial size. The server procedure is as shown in the first example.

static pthread_attr_t attr;

static int
create_server_thread(door_info_t *dip, void *(*startf)(void *),
    void *startfarg, void *crcookie)
{
    if (pthread_create(NULL, &attr, startf, startfarg) != 0)
        return (-1);
    return (1);
}

int
main(int argc, char *argv[])
{
    int did;

    (void) pthread_attr_init(&attr);
    (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    (void) pthread_attr_setstacksize(&attr, 128 * 1024);

    did = door_xcreate(server, NULL, DOOR_NO_DEPLETION_CB,
        create_server_thread, NULL, NULL, 4);
    if (did < 0) {
        perror("door_xcreate");
        exit(1);
    }
    [...]
}

The door_create() and door_xcreate() functions will fail if:

Invalid attributes are passed. This includes passing DOOR_NO_DEPLETION_CB to door_create().
The process has too many open descriptors.
The function was called from a vfork(2) child.

The door_xcreate() function will additionally fail if:

The nthread argument is too large.
A newly created server thread could not bind to the door's private pool.
The nthread argument is less than 1, thr_create_func is NULL, or thr_create_func returned 0 during the creation of the initial thread pool.
Memory allocation failed.
The thr_create_func function returned -1.

vfork(2), door_bind(3C), door_call(3C), door_info(3C), door_return(3C), door_revoke(3C), door_server_create(3C), door_setparam(3C), fattach(3C), pthread_create(3C), thr_create(3C), libdoor(3LIB), attributes(7), cancellation(7)

August 6, 2026 OmniOS