agt_create, agt_enumerate, agt_trap - map LWP events into messages
thread_t agt_create(agt, event, memory)
int agt_enumerate(vec, maxsize)
Agents are entities that act like threads sending messages when an
asynchronous event occurs. agt_create() creates an object called an
agent which maps the asynchronous event event into messages that can be
received with msg_recv() (see msg_send(3L)). agt stores the handle on
this object. event is a UNIX signal number.
agt_trap() causes the event, event, to generate an exception (see
exc_handle(3L)). Once initialized using agt_create() or agt_trap(), an
event can not be remapped to a different style of handling. If traps
are enabled, an event will cause the termination of the thread running
at the time of the trap if the trap exception is not handled. If an
exception handler is in place, an exception will be raised. If an
agent exists for the event, the event is mapped into a message for the
agent. If neither agent nor trap mapping is enabled, the default sig-
nal action (SIG_DFL) is applied to the pod. Use of standard UNIX sig-
nal handling facilities will defeat the event mapping mechanism.
The message sent by the agent (in the argument buffer) will look like
any other message with the sender being the agent. The receive buffer
is NULL. A message is always sent by an agent to the thread which cre-
ated the agent.
All messages sent by an agent contain an eventinfo_t. This structure
indicates the thread running at the time the interrupt happened, and
the particular event that occurred. Some agent messages contain more
information if the particular event warrants it. In this case, a
struct containing an eventinfo_t as its first element is passed as the
argument buffer. Definitions of these structures are contained in
An agent appears to the owning thread just like another thread. It
must therefore have some memory for holding its message, as the sender
and receiver must belong to the same address space. memory is the
space an agent will use to store its message. Typically, this is on
the stack of the thread that created the agent. It must be of the cor-
rect size for the kind of event being created (most events need some-
thing to store an eventinfo_t. SIGCHLD events need room for a
You should reply to an agent (using msg_reply() (see msg_send(3L)) as
you would reply to a thread. Although agents do not ordinarily lose
events, the next agent message will not be delivered until a reply is
sent to the agent. Thus, an agent appears to the client as an ordinary
thread sending messages. An agent will only lose events if the total
number of unreplied-to events in a pod exceeds AGENTMEMORY.
lwp_destroy() is used to destroy an agent. All agents created by a
thread automatically disappear when that thread dies. agt_enumerate()
fills in a list with the ID's of all existing agents and returns the
total number of agents. This primitive uses maxsize to avoid exceeding
the capacity of the list. If the number of agents is greater than max-
size, only maxsize agents ID's are filled in vec. If maxsize is zero,
agt_enumerate() returns the total number of agents.
The special event LASTRITES is caused by the termination of a thread.
An agent for LASTRITES will be informed about every thread that termi-
nates, regardless of cause. The eventinfo_code element of this agent
will contain the stack argument that the dead thread was created with.
Note: by allocating adjacent space above the thread stack, this argu-
ment can be used to point to private information about a thread. The
eventinfo_victimid element will contain the id of the dead thread.
agt_create() and agt_trap() return:
0 on success.
-1 on failure.
agt_enumerate() returns the total number of agents.
agt_trap() will fail if one or more of the following are true:
LE_INUSE Agent in use for this event.
LE_INVALIDARG Event specified does not exist.
agt_create() will fail if one or more of the following are true:
LE_INUSE Trap mapping in use for this event.
LE_INVALIDARG Attempt to create agent for non-existent event.
Signal handlers always take the SIG_DFL action when no agent manages
If a descriptor used by a parent of the pod (such as its standard
input) is marked non-blocking by a thread, it should be reset when the
pod terminates to prevent the parent from receiving EWOULDBLOCK errors
on the descriptor. There is no way to prevent this from happening if a
pod is terminated with extreme prejudice (for instance, using SIGKILL).
If an agent reports that a descriptor has I/O available, there may be
more than one occurrence of I/O available from that descriptor. Thus,
being informed that SIGIO has occurred on socket s may mean that there
are several messages waiting to be received from s. Clients should be
careful to clean out all I/O from a descriptor before going back to
All system calls should be protected with loops testing for EINTR (and
monitors if multiple threads can try to use system calls concurrently).
An lwp_sleep() could result in a hidden clock interrupt for example.
agt_trap() should not be used for asynchronous events. If an unsus-
pecting thread which has no exception handler is running at the time of
a trapped event, it will be terminated.
Clients should not normally handle signals themselves since the agent
mechanism assumes it is the only entity handling signals.
21 January 1990 AGT_CREATE(3L)