| The Casbah Project: APIs and Reference Manual: Developer's Release 1 | ||
|---|---|---|
| Prev | The Casbah Project: Qibla API | Next |
The following methods should be invoked by the Cairo Application Object Server only. Casbah application developers should not need to use these methods. A conformant Cairo implementation must invoke these methods in this order.
__cb_init__()(options).
__cb_setup__()
__cb_bind__()[1]
__cb_unbind__()
__cb_cleanup__()
In addition to these, __cb_info__() must also be implemented.
Table 1. __cb_get__ method
return type | method name | method arguments |
|---|---|---|
void | __cb_init__() | (CaDict options) |
__cb_init__() asks a Qibla driver instance to configure itself based on the options being handed to it. __cb_init__() is the constructor so it is only invoked when the system administrator is setting up a server. __cb_init__() must not be invoked at server startup by Cairo. __cb_init__() must not actually create any network sockets or attach to any shared memory segments. __cb_init__() must only fill in the instance variables of this object in preparation for a call to __cb_setup__()
Since each Qibla driver will speak a different protocol, each one will support different configuration options at bind time. This is possible because a CaDict is supplied to __cb_init__(). Any QiblaDriver which needs the options from the following table must use these names. All of the following are optional. A driver must use the default supplied in the following table if it requires an option that is not supplied. A driver may consider it an error if a required option is not in the table below and is not supplied in the input dictionary to the __cb_init__() method.
Table 2. __cb_init__() options
Datatype | Meaning | Default | Other | ? |
|---|---|---|---|---|
ip-address | CaString | IP address (in String form) that the driver must bind to. The special addresses "NULL" and "*" should bind to all addresses on the machine, and "localhost" or "loopback" should bind to the "loopback" address (127.0.0.1 in IPv4). | "*" | none required |
tcp-port | CaInt32 | Create a TCP socket and bind it to this port on the address supplied in ip-address. This option may be supplied along with the udp-port option. | no default | ip-address |
tcp-sockopt-backlog | CaInt32 | Set TCP accept queue depth. A value less than 1 must be viewed as using the operating system default value. (If no default exists for the OS, the largest possible queue must be used.) This value must only affect the TCP socket used to accept clients. | no default | tcp-port |
tcp-client-sockopt-sndbuffer | CaInt32 | Set the size of the TCP send buffer. This is a low-level OS setting that may not be available on all platforms. Drivers which cannot support this option must ignore it. This option must only affect the result client socket created by __cb_accept_one_client__(). It may affect the socket used to listen for connections. | operating system default | tcp-port |
tcp-client-sockopt-rcvbuffer | CaInt32 | Set the size of the TCP receive buffer. This is a low-level OS setting that may not be available on all platforms. Drivers which cannot support this option must ignore it. This option must only affect the result client socket created by __cb_accept_one_client__(). It may affect the socket used to listen for connections. | operating system default | tcp-port |
udp-port | CaInt32 | Create a UDP socket and bind it to this port on the address supplied in ip-address. This option may be supplied with the tcp-port option. | no default | ip-address |
unix-socket | CaString | String form of the Unix path at which to create a Unix socket. Unix sockets are only available on Unix-based operating systems. Some drivers may use this for a "higher-speed" connection. | no default | none required |
sysv-ipc-sem | CaInt32 | The id of a System V IPC semaphore. There is no way to supply IPC_PRIVATE. System V IPC is not available on all machines or configurations. | no default | none required |
sysv-ipc-shm | CaInt32 | The id of a System V IPC shared memory segment. There is no way to supply IPC_PRIVATE. System V IPC is not available on all machines or configurations. | no default | none required |
sysv-ipc-msg | CaInt32 | The id of a System V IPC message queue. There is no way to supply IPC_PRIVATE. System V IPC is not available on all machines or configurations. | no default | none required |
lock-file | CaString | The path of a file in the OS filesystem. This file may be used as a lock file to coordinate access to some shared resource like a shared memory buffer or a shared socket. This file must be created (if it does not exist) by the driver. The driver must not give an error if the file already exists, it must only return an error if it cannot use the file as a lock. The exact OS locking method used is up to the driver. | no default | none required |
shared-buffer-file | CaString | The path of a file in the OS filesystem. This file may be used as a shared memory buffer. The exact method of using this file as a shared buffer is left up to the driver. a A driver may use this file as an ordinary file, using normal read and write calls to move data into and out of it. | no default | none required |
unix-fifo | CaString | The path of a file in the base operating system's file system. This file should be used as a FIFO queue. FIFOs are special files handled by the Unix operating system kernel that allows writers and readers to write to (and read from) a file as if it were a network stream. | no default | none required |
| Notes: a. Common schemes are mmap(2) (on Unix), or shared arenas on SGI's Irix. | ||||
The options tcp-client-sockopt-sndbuffer and tcp-client-sockopt-rcvbuffer are placed here to allow runtime fine-tuning of driver instances. These must be used with extreme attention to detail. Driver authors should support these options; but they may override the option value with their own values tuned for their specific driver.
Table 3. __cb_setup__() method
return type | method name | method arguments |
|---|---|---|
CaBoolean | __cb_setup__() | () |
__cb_setup__() asks the driver instance to create any shared memory segments that it needs, or to clear and setup any locks or memory buffers that it requires. __cb_setup__() must be invoked only once, in a single thread, prior to __cb_bind__() being invoked.
__cb_setup__() should create any shared memory segments that are not defined yet, and it must also initalize them to a known state. [3] __cb_bind__() will be executed in multiple independent threads simultaneously; it should, therefore, only create network sockets or attach to shared memory segments.
Note: the driver must return immediately from this method when the setup is complete; i.e., it must not block in an event-loop. The purpose of this method is only to begin to create the server socket, not to handle incoming client connections.
__cb_setup__() must return TRUE if the setup procedure was successful, otherwise it should throw an appropriate exception. __cb_setup__() may return FALSE, applications must expect a return value of FALSE. If FALSE is returned by __cb_setup__() __cb_bind__() must not be called.
Table 4. __cb_bind__() method
return type | method name | method arguments |
|---|---|---|
CaBoolean | __cb_bind__() | () |
__cb_bind__() will be invoked by Cairo multiple times. In a Cairo Application Object Server that is implemented using multiple Unix processes, it will be necessary to invoke __cb_bind__() in each process. __cb_bind__() should actually create and configure the sockets, attach to shared memory segments or semaphores, and open any necessary files (such as locks or FIFOs). After __cb_bind__() completes, the driver should be ready to invoke __cb_accept_one_client__().
On platforms that support it, the author must use setsockopt(2) to configure the socket so that Cairo can reuse the local address (setsockopt option is SO_REUSEADDR). This is an important detail that shouldn't be neglected: some implementations of Cairo will rely on it.
__cb_bind__() must return TRUE if the bind procedure was successful, otherwise it should throw an appropiate error. __cb_bind__() may return FALSE, applications must expect a return value of FALSE. If __cb_bind__() returns FALSE, __cb_unbind__() must be called in all processes in which __cb_bind__() returned TRUE, followed by a call to __cb_cleanup__().
Table 5. __cb_accept_one_client__() method
return type | method name | method arguments |
|---|---|---|
CaBoolean | __cb_accept_one_client__() | () |
Accept a single client and return an object to hold all data associated with a connection. This method should be used to get the client attached to the server and to obtain information about how the client is connected [4] For most protocols, actual protocol conversations should be delayed until the call to __cb_handle_connection__().
Cairo must ensure that only one thread at any point in time may execute __cb_accept_one_client__().
The object returned must be of a type created by the QiblaDriver author in order to hold the state of the connection. This object must implement the __cb_handle_connection__() method, and must be subclassed from QiblaConnection.
If the QiblaDriver author needs to access the QiblaDriver instance while inside of the method __cb_handle_connection__() a pointer to the driver instance must be stored in the client object that is returned. Access to the QiblaDriver instance is restricted while inside of __cb_handle_connection__(). See __cb_handle_connection__() for more information.
Table 6. __cb_unbind__() method
return type | method name | method arguments |
|---|---|---|
void | __cb_unbind__() | () |
Unbinds the communications sockets used by this instance of the driver. __cb_unbind__() closes any listen sockets and stops accepting connections in the current process. __cb_unbind__() must detach from any shared memory segments that the driver is utilizing or any inter-process locks/semaphores to which the driver has attached.
A driver must not be unbound until all of its currently active connections have closed and all __cb_handle_connection__() calls have returned. This allows the QiblaDriver to store global state information in the driver instance itself.
Any clients that may be queued up waiting for a call to __cb_accept_one_client__() must be disconnected and thrown away when __cb_unbind__() is invoked.
__cb_unbind__() must be invoked once per process. __cb_cleanup__() will be invoked once, allowing the driver to cleanup shared memory segments or files that are left around. See __cb_cleanup__().
Table 7. __cb_cleanup__() method
return type | method name | method arguments |
|---|---|---|
void | __cb_cleanup__() | () |
__cb_cleanup__() must be invoked only once for a Cairo server instance. After __cb_cleanup__() is invoked, __cb_setup__() must be invoked in order to begin restarting services offered by Cairo. __cb_cleanup__() must be invoked in a single thread of execution. __cb_cleanup__() must be invoked after all processes, including the one that is invoking __cb_cleanup__(), have invoked __cb_unbind__() on this driver.
The __cb_info__() method must be implemented in QiblaDriver. __cb_info__() returns a dictionary of driver metadata. The following key/value pairs must be returned in __cb_info__()'s dictionary.
Table 8. __cb_info__() method
return type | method name | method arguments |
|---|---|---|
CaDict | __cb_info__ | () |
Table 9. __cb_info__() key/value pairs
Key Name (type) | Example Value (type) | Description |
|---|---|---|
name (CaString) | QiblaHTTP (CaString) | A short, descriptive filename-like name for the driver. |
description (CaString) (CaString) | Provides HTTP protocol access to Cairo Application Object Server (CaString) | A sentence or two that describes the functions the driver performs. |
author (CaString) | Scott Miller (CaString) | The full name of the primary developer of the driver. |
contact (CaString) | <scgmille@casbah.org> (CaString) | Contact information for the driver author; typically an email address. |
api (CaString) | qibla driver (CaString) | Specifies which API the driver implements. For QiblaDriver objects, this is always the string "qibla driver". |
revision (CaString) | 1.15 (CaString) | The CVS driver revision. Used for quality control and support. This is not the API version number. |
resource (CaList) | tcpip-port/2853 | Contains a CaList of mapped resources the driver is using |
Table 10. __cb_cleanup__() method
return type | method name | method arguments |
|---|---|---|
CaInt32 | __cb_listen_socket__() | () |
Allows a QiblaDriver to optimize itself for a Cairo server. __cb_listen_socket__() returns a file descriptor which can be placed into a select(2) call with other file descriptors, allowing a Cairo server to use only one thread to handle multiple QiblaDriver instances. A Cairo server must not require this method for QiblaDrivers to function correctly. Driver may return a value of -1 to indicate that no listen socket is appropiate for the instance. A Cairo server must recognize a return value of -1 as equivlant to __cb_listen_socket__() not being implemented. This method may not function at all in some OSes.[5]
| [1] | Can be called multiple times, once per process. while(TRUE) |
| [3] | These two actions are necessary only if the driver utilizes shared memory segments or mutexes. |
| [4] | For example, the IP address that the client is connected to. |
| [5] | See accept(2) and select(2) manpages on a Unix machine. The socket returned by listen_socket should be the same socket as used by accept(2), and should be placed in non-blocking mode. |