Client message dispatcher. More...
Related Functions | |
(Note that these are not member functions.) | |
| adbus_Connection * | adbus_conn_new (adbus_ConnectionCallbacks *cb, void *user) |
| Creates a new connection. | |
| void | adbus_conn_ref (adbus_Connection *connection) |
| Increments the connection ref count. | |
| void | adbus_conn_deref (adbus_Connection *c) |
| Decrements the connection ref count. | |
| int | adbus_conn_send (adbus_Connection *c, adbus_Message *message) |
| Sends a message on the connection. | |
| uint32_t | adbus_conn_serial (adbus_Connection *c) |
| Gets a serial that can be used for sending messages. | |
| int | adbus_conn_dispatch (adbus_Connection *c, adbus_Message *message) |
| Dispatch a pre-parsed message. | |
| int | adbus_conn_parse (adbus_Connection *c, adbus_Buffer *buf) |
| Consume messages from the supplied buffer. | |
| adbus_Bool | adbus_conn_shouldproxy (adbus_Connection *c) |
| See if calling code should use adbus_conn_proxy(). | |
| void | adbus_conn_proxy (adbus_Connection *c, adbus_Callback callback, void *user) |
| Proxy a call over to the connection thread or call immediately if already on it. | |
| void | adbus_conn_getproxy (adbus_Connection *c, adbus_ProxyCallback *cb, adbus_ProxyMsgCallback *msgcb, void **user) |
| Get proxy functions for the current thread. | |
| adbus_ConnReply * | adbus_conn_addreply (adbus_Connection *c, const adbus_Reply *reg) |
| Registers a reply with the connection. | |
| void | adbus_conn_removereply (adbus_Connection *c, adbus_ConnReply *reply) |
| Unregisters a reply from the connection. | |
Client message dispatcher.
The connection API can be split into four sections:
The connection itself has no idea how to get incoming data or messages. Instead the owner of the connection figures out how to get incoming data off of a socket and feeds it into the connection via adbus_conn_dispatch() or adbus_conn_parse().
The simplest way of handing data off to the connection is to append data to an adbus_Buffer and then having the connection consume complete messages in the buffer via adbus_conn_parse(). For example:
#define RECV_SIZE 64 * 1024 int ReadSignalled() { // Read all the data available adbus_ssize_t read = RECV_SIZE; while (read == RECV_SIZE) { // adbus_buf_recvbuf() gives us a place at the end of the buffer // to hand off to recv where it can put the data uint8_t* buf = adbus_buf_recvbuf(my_buffer, RECV_SIZE); read = recv(my_socket, RECV_SIZE, 0); adbus_buf_recvd(my_buffer, RECV_SIZE, read); } // Hand the data off to the connection. If adbus_conn_parse returns // an error, we should disconnect the socket. if (adbus_conn_parse(my_connection, my_buffer)) return -2; // Propagate recv errors up if (read < 0) return -1; return 0; }
Outgoing data is sent via adbus_ConnectionCallbacks::send_message set with adbus_conn_new(). This is required to be always set.
For example:
static int SendMessage(void* user, adbus_Message* msg) { adbus_Socket* s = (adbus_Socket*) user; return send(*s, msg->data, msg->size, 0); } adbus_Connection* CreateConnection(adbus_Socket sock) { adbus_ConnectionCallbacks cbs = {}; cbs.send_message = &SendMessage; return adbus_conn_new(&cbs, (void*) &sock); }
In multithreaded applications, the connection parsing and dispatch will be on a given thread, but we often want to register objects and callbacks for all of the application's thread on the one thread. The way we get around this is to proxy all messages and requests for registrations to and from the connection thread.
This proxying of messages to and fro is done via the proxy callbacks setup in adbus_conn_new(). See proxy, should_proxy, get_proxy, and block in adbus_ConnectionCallbacks.
See adbus_Bind, adbus_Match, and adbus_Reply.
By default the connection will not connect to the bus server (specifically it does not send the Hello message), until adbus_conn_connect() is called. This is especially useful for multithreaded applications that want to create a connection, register all of their objects on the various app threads, and then finally connect to the bus. This then avoids race conditions when other applications try to call method for not yet registered objects.
Once the server responds to the hello message adbus_conn_isconnected() will return true and adbus_conn_uniquename() will return the assigned name.
| adbus_ConnReply * adbus_conn_addreply | ( | adbus_Connection * | c, | |
| const adbus_Reply * | reg | |||
| ) | [related] |
Registers a reply with the connection.
| void adbus_conn_getproxy | ( | adbus_Connection * | c, | |
| adbus_ProxyCallback * | cb, | |||
| adbus_ProxyMsgCallback * | msgcb, | |||
| void ** | user | |||
| ) | [related] |
Get proxy functions for the current thread.
The arguments may be null if that value is not needed.
| int adbus_conn_parse | ( | adbus_Connection * | c, | |
| adbus_Buffer * | buf | |||
| ) | [related] |
Consume messages from the supplied buffer.
This will remove all complete messages from the beginning of the buffer, but it will leave incomplete messages in the buffer. These should be appended to once more data comes in and then recall this function.
| void adbus_conn_proxy | ( | adbus_Connection * | c, | |
| adbus_Callback | callback, | |||
| void * | user | |||
| ) | [related] |
Proxy a call over to the connection thread or call immediately if already on it.
| void adbus_conn_removereply | ( | adbus_Connection * | c, | |
| adbus_ConnReply * | reply | |||
| ) | [related] |
Unregisters a reply from the connection.
If in C code, you should probably use adbus_State rather than calling this directly as it manages the disconnects and thread issues.
| int adbus_conn_send | ( | adbus_Connection * | c, | |
| adbus_Message * | message | |||
| ) | [related] |
Sends a message on the connection.
This function is thread safe and may be called in both callbacks and on other threads.
| uint32_t adbus_conn_serial | ( | adbus_Connection * | c | ) | [related] |
Gets a serial that can be used for sending messages.
| adbus_Bool adbus_conn_shouldproxy | ( | adbus_Connection * | c | ) | [related] |
See if calling code should use adbus_conn_proxy().
1.6.1