Download
Proxies

Contact
About
Docs
CVS

Reference: Proxies

General

A proxy is a single-process event multiplexer. It takes control of the execution flow, and waits in a nice way for something to happen that requires your program's attention. This is typically caused by user input or other processes (remote or local) signalling your process, connecting to public services it offers, etc.

Properties overview

  • Multiple subsystems. Handles different kinds of subsystems simultaneously.
  • Multiple instances per subsystem. Handles any number of subsystem instances (e.g. sockets or timers).
  • Specific handlers per instance. Each instance has specific handler slots that can be registered with. Only one function can be attached to any single event on an instance. Exception: Subsystems that do filtering, like COMM.

Events

Events are handled for the following subsystems:
  • Sockets, SOCK.
  • Block communications, COMM.
  • Timers.
These are the prototypes for your event handlers, along with invocation semantics - sorted by subsystem:

SOCK

  • int read(SOCK *s, void *priv);
    Invoked whenever there is data to be read from the socket s. The data you passed upon registering is passed back to you in priv.
     
  • int write(SOCK *s, void *priv);
    Invoked whenever socket s can be written to. This doesn't neccessarily mean you can write as much as you want, so beware. The data you passed upon registering is passed back to you in priv.
     
  • int connect(SOCK *sp, SOCK *s, void *priv);
    Invoked whenever a connection attempt involving the socket sp is resolved. The semantics are a little different for incoming and outgoing connections: For successful incoming connections, you get a new, connected socket in s. For outgoing connections, s will be NULL, and you have to check if sp is connected, to determine if your attempt was successful. If it is not, this indicates a failed outgoing connection attempt. The data you passed upon registering the handler is passed back to you in priv.
     
  • int close(SOCK *s, void *priv);
    Invoked whenever the remote end closes a connection to your socket. Not invoked for sockets you've closed in your end. Upon invocation, the socket is not closed in your end - you have to take care of this yourself. The data you passed upon registering is passed back to you in priv.
COMM
  • int recv(COMM *c, TT *tt, ushort trans, int complete, void *priv);
    Invoked whenever c receives a tree, or a node in a tree, matching the transaction and root this handler was registered with. If the handler was registered as accepting incomplete trees (tree nodes), complete can be FALSE, in which case tt is the last received node, prepared with data and connected to the rest of the tree. Any handler, whether accepting part-trees or not, can receive a complete tree. In that case, tt is the root node of the complete tree. The data you passed upon registering is passed back to you in priv.
     
  • int connect(COMM *cp, COMM *c, void *priv);
    Invoked whenever a connection attempt involving the comm cp is resolved. The semantics is a little different for incoming and outgoing connections: For successful incoming connections, you get a new, connected comm in c. For outgoing connections, c will be NULL, and you have to check if cp is connected, to determine if your attempt was successful. If it is not, this indicates a failed outgoing connection attempt. The data you passed upon registering the handler is passed back to you in priv.
     
  • void close(COMM *c, void *priv);
    Invoked whenever the remote end closes a connection to your comm. Not invoked for comms you've closed in your end. Upon invocation, the comm is not closed in your end - you have to take care of this yourself. The data you passed upon registering is passed back to you in priv.
Timer
  • int timeout(char *name, void *priv);
    Invoked whenever the timer name times out. The data you passed upon registering is passed back to you in priv.

Allocation

  • PROXY *proxy_new();
    Allocates, initializes to empty and returns a new proxy.
     
  • void proxy_del(PROXY *p);
    Deletes all handlers and the proxy, p, itself. Never delete a proxy within one of its handlers. This should be done outside the loop, i.e. on the level that initialized and started the proxy in the first place.

Running

  • void proxy_loop(PROXY *p);
    Starts the proxy loop for proxy p. This loop will activate event handlers in your source as things happen. Activating an empty proxy is not a good idea. Keeps running until proxy_break is called on it from a handler.
     
  • void proxy_break(PROXY *p);
    Makes a proxy stop executing. Usually, you will call this from within one of its handlers. The proxy_loop function will return to its caller as soon as control is returned to the proxy (when your current handler exits).

Adding handlers

  • void proxy_add_sock(PROXY *p, SOCK *s, void *priv, int (*read)(SOCK *, void *), int (*write)(SOCK *, void *), int (*connect)(SOCK *, SOCK *, void *), int (*close)(SOCK *, void *));
    Add handlers to proxy p for socket s, potentially for all possible socket events at once. Any combination of the function pointers read, write, connect and close can be NULL, in which case that handler for the specified socket, is not touched.
     
  • void proxy_add_sock_read(PROXY *p, SOCK *s, void *priv, int (*read)(SOCK *, void *));
    Set read handler for socket s in proxy p. Data set in priv is passed back to the handler upon invocation.
     
  • void proxy_add_sock_write(PROXY *p, SOCK *s, void *priv, int (*write)(SOCK *, void *));
    Set write handler for socket s in proxy p. Data set in priv is passed back to the handler upon invocation.
     
  • void proxy_add_sock_connect(PROXY *p, SOCK *s, void *priv, int (*connect)(SOCK *, void *));
    Set connection handler for socket s in proxy p. Data set in priv is passed back to the handler upon invocation.
     
  • void proxy_add_sock_close(PROXY *p, SOCK *s, void *priv, int (*close)(SOCK *, void *));
    Set close handler for socket s in proxy p. Data set in priv is passed back to the handler upon invocation.
     
  • void proxy_add_comm(PROXY *p, COMM *c, char *root, ushort trans, int incomplete, void *priv, int (*recv)(COMM *, TT *, ushort, int, void *));
    Adds a handler for incoming token trees on comm c in proxy p. root is the root string the trees must match, and trans is the transaction number they must match. If either is NULL or zero, that argument means catch-any-root or catch-any-trans. If root is NULL and trans is zero, this handler will be a default handler, i.e. it gets all incoming trees. If incomplete is TRUE, the handler will be invoked as the tree is constructed, with each finished node (see the Events section above). You can have any number of these handlers, and their characteristics may overlap in part or in full.
     
  • void proxy_add_comm_connect(PROXY *p, COMM *c, void *priv, int (*connect)(COMM *, COMM *, void *));
    Set connection handler for comm c in proxy p. Data set in priv is passed back to the handler upon invocation.
     
  • void proxy_add_comm_close(PROXY *p, COMM *c, void *priv, int (*close)(COMM *, void *));
    Set close handler for comm c in proxy p. Data set in priv is passed back to the handler upon invocation.
     
  • void proxy_add_timer(PROXY *p, char *name, struct timeval *interval, int recurrent, void *priv, int (*timeout)(char *, void *));
    Set a timer-invoked function. The timer's unique name (passed to the function and used for identification, e.g. when deleting the handler) will be name. The function timeout will be invoked at intervals defined by interval, first invocation being the time span defined by interval, from now. If recurrent is TRUE, timeout will be invoked until the handler is removed manually, otherwise it is just invoked once (the handler goes away afterwards).

Deleting handlers

  • void proxy_del_sock(PROXY *p, SOCK *s);
    Removes the handlers for socket s from proxy p. You will get no more events for the socket. This must be done before deleting the socket structure itself.
     
  • void proxy_del_comm(PROXY *p, COMM *c);
    Removes the handlers for comm c from proxy p. You will get no more events for the comm. This must be done before deleting the comm structure itself.
     
  • void proxy_del_comm_trans(PROXY *p, COMM *c, u16 trans);
    Removes the handlers matching transaction trans for comm c from proxy p.
     
  • void proxy_del_comm_block(PROXY *p, COMM *c, char *root);
    Removes the handlers matching root string root for comm c from proxy p.
     
  • void proxy_del_timer(PROXY *p, char *name);
    Removes the timer named name from proxy p.

Special interfaces

  • void proxy_reset_timer(PROXY *p, char *name);
    Resets countdown for timer named name, so the next invocation will occur in the pre-set interval, from now.

 

 

Flux, these web pages, and all related material are Copyright©1999-2000 Simplemente and the respective authors, and are licensed under the GNU GPL. Please see the About page for more details. Web design by Joakim Ziegler <joakim@simplemente.net>, illustrations by Belinda Laws, <boysdontcry@zombieworld.com>.