varlink: add ability to register callback for disconnections

This commit is contained in:
Lennart Poettering 2019-11-27 14:43:41 +01:00
parent c4f601f205
commit 6d4d600260
2 changed files with 23 additions and 2 deletions

View File

@ -168,6 +168,7 @@ struct VarlinkServer {
Hashmap *methods;
VarlinkConnect connect_callback;
VarlinkDisconnect disconnect_callback;
sd_event *event;
int64_t event_priority;
@ -1146,6 +1147,7 @@ int varlink_flush(Varlink *v) {
}
static void varlink_detach_server(Varlink *v) {
VarlinkServer *saved_server;
assert(v);
if (!v->server)
@ -1169,8 +1171,15 @@ static void varlink_detach_server(Varlink *v) {
v->server->n_connections--;
/* If this is a connection associated to a server, then let's disconnect the server and the
* connection from each other. This drops the dangling reference that connect_callback() set up. */
v->server = varlink_server_unref(v->server);
* connection from each other. This drops the dangling reference that connect_callback() set up. But
* before we release the references, let's call the disconnection callback if it is defined. */
saved_server = TAKE_PTR(v->server);
if (saved_server->disconnect_callback)
saved_server->disconnect_callback(saved_server, v, saved_server->userdata);
varlink_server_unref(saved_server);
varlink_unref(v);
}
@ -2413,6 +2422,16 @@ int varlink_server_bind_connect(VarlinkServer *s, VarlinkConnect callback) {
return 0;
}
int varlink_server_bind_disconnect(VarlinkServer *s, VarlinkDisconnect callback) {
assert_return(s, -EINVAL);
if (callback && s->disconnect_callback && callback != s->disconnect_callback)
return -EBUSY;
s->disconnect_callback = callback;
return 0;
}
unsigned varlink_server_connections_max(VarlinkServer *s) {
int dts;

View File

@ -51,6 +51,7 @@ typedef enum VarlinkServerFlags {
typedef int (*VarlinkMethod)(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata);
typedef int (*VarlinkReply)(Varlink *link, JsonVariant *parameters, const char *error_id, VarlinkReplyFlags flags, void *userdata);
typedef int (*VarlinkConnect)(VarlinkServer *server, Varlink *link, void *userdata);
typedef void (*VarlinkDisconnect)(VarlinkServer *server, Varlink *link, void *userdata);
int varlink_connect_address(Varlink **ret, const char *address);
int varlink_connect_fd(Varlink **ret, int fd);
@ -134,6 +135,7 @@ int varlink_server_bind_method(VarlinkServer *s, const char *method, VarlinkMeth
int varlink_server_bind_method_many_internal(VarlinkServer *s, ...);
#define varlink_server_bind_method_many(s, ...) varlink_server_bind_method_many_internal(s, __VA_ARGS__, NULL)
int varlink_server_bind_connect(VarlinkServer *s, VarlinkConnect connect);
int varlink_server_bind_disconnect(VarlinkServer *s, VarlinkDisconnect disconnect);
void* varlink_server_set_userdata(VarlinkServer *s, void *userdata);
void* varlink_server_get_userdata(VarlinkServer *s);