mirror of git://git.sysmocom.de/ofono
gisi: simplify pending management
Client or server mark their pending objects with the function g_isi_pending_set_owner(). When client or server get destroyed or reset the pending objects are removed with the function g_isi_remove_pending_by_owner(). As a client or server always uses only a particular resource, all the pending objects are conveniently stored into a single list.
This commit is contained in:
parent
fef6de49af
commit
e72e5444af
199
gisi/client.c
199
gisi/client.c
|
@ -32,58 +32,12 @@
|
||||||
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
|
||||||
struct pending_data {
|
|
||||||
GIsiClient *client;
|
|
||||||
GIsiNotifyFunc notify;
|
|
||||||
void *data;
|
|
||||||
GDestroyNotify destroy;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GIsiClient {
|
struct _GIsiClient {
|
||||||
GIsiModem *modem;
|
GIsiModem *modem;
|
||||||
unsigned timeout;
|
unsigned timeout;
|
||||||
uint8_t resource;
|
uint8_t resource;
|
||||||
GSList *pending;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pending_destroy(gpointer data)
|
|
||||||
{
|
|
||||||
struct pending_data *pd = data;
|
|
||||||
|
|
||||||
if (pd == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (pd->destroy != NULL)
|
|
||||||
pd->destroy(pd->data);
|
|
||||||
|
|
||||||
g_free(pd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pending_resp_notify(const GIsiMessage *msg, void *data)
|
|
||||||
{
|
|
||||||
struct pending_data *pd = data;
|
|
||||||
|
|
||||||
if (pd == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pd->client->pending = g_slist_remove(pd->client->pending,
|
|
||||||
g_isi_pending_from_msg(msg));
|
|
||||||
|
|
||||||
if (pd->notify != NULL)
|
|
||||||
pd->notify(msg, pd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pending_notify(const GIsiMessage *msg, void *data)
|
|
||||||
{
|
|
||||||
struct pending_data *pd = data;
|
|
||||||
|
|
||||||
if (pd == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (pd->notify != NULL)
|
|
||||||
pd->notify(msg, pd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t g_isi_client_resource(GIsiClient *client)
|
uint8_t g_isi_client_resource(GIsiClient *client)
|
||||||
{
|
{
|
||||||
return client != NULL ? client->resource : 0;
|
return client != NULL ? client->resource : 0;
|
||||||
|
@ -112,31 +66,13 @@ GIsiClient *g_isi_client_create(GIsiModem *modem, uint8_t resource)
|
||||||
client->timeout = G_ISI_CLIENT_DEFAULT_TIMEOUT;
|
client->timeout = G_ISI_CLIENT_DEFAULT_TIMEOUT;
|
||||||
client->resource = resource;
|
client->resource = resource;
|
||||||
client->modem = modem;
|
client->modem = modem;
|
||||||
client->pending = NULL;
|
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void foreach_destroy(gpointer value, gpointer user)
|
|
||||||
{
|
|
||||||
GIsiPending *op = value;
|
|
||||||
GIsiClient *client = user;
|
|
||||||
|
|
||||||
if (op == NULL || client == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
client->pending = g_slist_remove(client->pending, op);
|
|
||||||
g_isi_pending_remove(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
void g_isi_client_reset(GIsiClient *client)
|
void g_isi_client_reset(GIsiClient *client)
|
||||||
{
|
{
|
||||||
if (client == NULL || client->pending == NULL)
|
g_isi_remove_pending_by_owner(client->modem, client->resource, client);
|
||||||
return;
|
|
||||||
|
|
||||||
g_slist_foreach(client->pending, foreach_destroy, client);
|
|
||||||
g_slist_free(client->pending);
|
|
||||||
client->pending = NULL;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void g_isi_client_destroy(GIsiClient *client)
|
void g_isi_client_destroy(GIsiClient *client)
|
||||||
|
@ -156,43 +92,19 @@ void g_isi_client_set_timeout(GIsiClient *client, unsigned timeout)
|
||||||
client->timeout = timeout;
|
client->timeout = timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pending_data *pending_data_create(GIsiClient *client,
|
|
||||||
GIsiNotifyFunc notify,
|
|
||||||
void *data,
|
|
||||||
GDestroyNotify destroy)
|
|
||||||
{
|
|
||||||
struct pending_data *pd;
|
|
||||||
|
|
||||||
if (client == NULL) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pd = g_try_new0(struct pending_data, 1);
|
|
||||||
if (pd == NULL) {
|
|
||||||
errno = ENOMEM;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pd->client = client;
|
|
||||||
pd->notify = notify;
|
|
||||||
pd->data = data;
|
|
||||||
pd->destroy = destroy;
|
|
||||||
|
|
||||||
return pd;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean g_isi_client_send(GIsiClient *client,
|
gboolean g_isi_client_send(GIsiClient *client,
|
||||||
const void *__restrict msg, size_t len,
|
const void *__restrict msg, size_t len,
|
||||||
GIsiNotifyFunc notify, void *data,
|
GIsiNotifyFunc notify, void *data,
|
||||||
GDestroyNotify destroy)
|
GDestroyNotify destroy)
|
||||||
{
|
{
|
||||||
if (client == NULL)
|
GIsiPending *op;
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return g_isi_client_send_with_timeout(client, msg, len,
|
op = g_isi_request_send(client->modem, client->resource, msg, len,
|
||||||
client->timeout,
|
client->timeout, notify, data, destroy);
|
||||||
notify, data, destroy);
|
|
||||||
|
g_isi_pending_set_owner(op, client);
|
||||||
|
|
||||||
|
return op != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean g_isi_client_send_with_timeout(GIsiClient *client,
|
gboolean g_isi_client_send_with_timeout(GIsiClient *client,
|
||||||
|
@ -201,23 +113,14 @@ gboolean g_isi_client_send_with_timeout(GIsiClient *client,
|
||||||
GIsiNotifyFunc notify, void *data,
|
GIsiNotifyFunc notify, void *data,
|
||||||
GDestroyNotify destroy)
|
GDestroyNotify destroy)
|
||||||
{
|
{
|
||||||
struct pending_data *pd;
|
|
||||||
GIsiPending *op;
|
GIsiPending *op;
|
||||||
|
|
||||||
pd = pending_data_create(client, notify, data, destroy);
|
|
||||||
if (pd == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
op = g_isi_request_send(client->modem, client->resource, buf, len,
|
op = g_isi_request_send(client->modem, client->resource, buf, len,
|
||||||
timeout, pending_resp_notify, pd,
|
timeout, notify, data, destroy);
|
||||||
pending_destroy);
|
|
||||||
if (op == NULL) {
|
|
||||||
g_free(pd);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
client->pending = g_slist_append(client->pending, op);
|
g_isi_pending_set_owner(op, client);
|
||||||
return TRUE;
|
|
||||||
|
return op != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean g_isi_client_vsend(GIsiClient *client,
|
gboolean g_isi_client_vsend(GIsiClient *client,
|
||||||
|
@ -225,12 +128,14 @@ gboolean g_isi_client_vsend(GIsiClient *client,
|
||||||
GIsiNotifyFunc notify, void *data,
|
GIsiNotifyFunc notify, void *data,
|
||||||
GDestroyNotify destroy)
|
GDestroyNotify destroy)
|
||||||
{
|
{
|
||||||
if (client == NULL)
|
GIsiPending *op;
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return g_isi_client_vsend_with_timeout(client, iov, iovlen,
|
op = g_isi_request_vsend(client->modem, client->resource, iov, iovlen,
|
||||||
client->timeout,
|
client->timeout, notify, data, destroy);
|
||||||
notify, data, destroy);
|
|
||||||
|
g_isi_pending_set_owner(op, client);
|
||||||
|
|
||||||
|
return op != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean g_isi_client_vsend_with_timeout(GIsiClient *client,
|
gboolean g_isi_client_vsend_with_timeout(GIsiClient *client,
|
||||||
|
@ -239,85 +144,51 @@ gboolean g_isi_client_vsend_with_timeout(GIsiClient *client,
|
||||||
GIsiNotifyFunc notify, void *data,
|
GIsiNotifyFunc notify, void *data,
|
||||||
GDestroyNotify destroy)
|
GDestroyNotify destroy)
|
||||||
{
|
{
|
||||||
struct pending_data *pd;
|
|
||||||
GIsiPending *op;
|
GIsiPending *op;
|
||||||
|
|
||||||
pd = pending_data_create(client, notify, data, destroy);
|
|
||||||
if (pd == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
op = g_isi_request_vsend(client->modem, client->resource, iov, iovlen,
|
op = g_isi_request_vsend(client->modem, client->resource, iov, iovlen,
|
||||||
timeout, pending_resp_notify, pd,
|
timeout, notify, data, destroy);
|
||||||
pending_destroy);
|
|
||||||
if (op == NULL) {
|
|
||||||
g_free(pd);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
client->pending = g_slist_append(client->pending, op);
|
g_isi_pending_set_owner(op, client);
|
||||||
return TRUE;
|
|
||||||
|
return op != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean g_isi_client_ind_subscribe(GIsiClient *client, uint8_t type,
|
gboolean g_isi_client_ind_subscribe(GIsiClient *client, uint8_t type,
|
||||||
GIsiNotifyFunc notify, void *data)
|
GIsiNotifyFunc notify, void *data)
|
||||||
{
|
{
|
||||||
struct pending_data *pd;
|
|
||||||
GIsiPending *op;
|
GIsiPending *op;
|
||||||
|
|
||||||
pd = pending_data_create(client, notify, data, NULL);
|
|
||||||
if (pd == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
op = g_isi_ind_subscribe(client->modem, client->resource, type,
|
op = g_isi_ind_subscribe(client->modem, client->resource, type,
|
||||||
pending_notify, pd, pending_destroy);
|
notify, data, NULL);
|
||||||
if (op == NULL) {
|
|
||||||
g_free(pd);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
client->pending = g_slist_append(client->pending, op);
|
g_isi_pending_set_owner(op, client);
|
||||||
return TRUE;
|
|
||||||
|
return op != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean g_isi_client_ntf_subscribe(GIsiClient *client, uint8_t type,
|
gboolean g_isi_client_ntf_subscribe(GIsiClient *client, uint8_t type,
|
||||||
GIsiNotifyFunc notify, void *data)
|
GIsiNotifyFunc notify, void *data)
|
||||||
{
|
{
|
||||||
struct pending_data *pd;
|
|
||||||
GIsiPending *op;
|
GIsiPending *op;
|
||||||
|
|
||||||
pd = pending_data_create(client, notify, data, NULL);
|
|
||||||
if (pd == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
op = g_isi_ntf_subscribe(client->modem, client->resource, type,
|
op = g_isi_ntf_subscribe(client->modem, client->resource, type,
|
||||||
pending_notify, pd, pending_destroy);
|
notify, data, NULL);
|
||||||
if (op == NULL) {
|
|
||||||
g_free(pd);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
client->pending = g_slist_append(client->pending, op);
|
g_isi_pending_set_owner(op, client);
|
||||||
return TRUE;
|
|
||||||
|
return op != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean g_isi_client_verify(GIsiClient *client, GIsiNotifyFunc notify,
|
gboolean g_isi_client_verify(GIsiClient *client, GIsiNotifyFunc notify,
|
||||||
void *data, GDestroyNotify destroy)
|
void *data, GDestroyNotify destroy)
|
||||||
{
|
{
|
||||||
struct pending_data *pd;
|
|
||||||
GIsiPending *op;
|
GIsiPending *op;
|
||||||
|
|
||||||
pd = pending_data_create(client, notify, data, destroy);
|
|
||||||
if (pd == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
op = g_isi_resource_ping(client->modem, client->resource,
|
op = g_isi_resource_ping(client->modem, client->resource,
|
||||||
pending_resp_notify, pd,
|
notify, data, destroy);
|
||||||
pending_destroy);
|
|
||||||
if (op == NULL) {
|
|
||||||
g_free(pd);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
client->pending = g_slist_append(client->pending, op);
|
g_isi_pending_set_owner(op, client);
|
||||||
return TRUE;
|
|
||||||
|
return op != NULL;
|
||||||
}
|
}
|
||||||
|
|
63
gisi/modem.c
63
gisi/modem.c
|
@ -73,6 +73,7 @@ struct _GIsiModem {
|
||||||
struct _GIsiPending {
|
struct _GIsiPending {
|
||||||
enum GIsiMessageType type;
|
enum GIsiMessageType type;
|
||||||
GIsiServiceMux *service;
|
GIsiServiceMux *service;
|
||||||
|
gpointer owner;
|
||||||
guint timeout;
|
guint timeout;
|
||||||
GIsiNotifyFunc notify;
|
GIsiNotifyFunc notify;
|
||||||
GDestroyNotify destroy;
|
GDestroyNotify destroy;
|
||||||
|
@ -799,6 +800,68 @@ void g_isi_pending_remove(GIsiPending *op)
|
||||||
pending_destroy(op, NULL);
|
pending_destroy(op, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void foreach_destroy(GIsiPending *op)
|
||||||
|
{
|
||||||
|
if (op->type == GISI_MESSAGE_TYPE_IND)
|
||||||
|
service_subs_decr(op->service);
|
||||||
|
|
||||||
|
if (op->type == GISI_MESSAGE_TYPE_REQ)
|
||||||
|
service_regs_decr(op->service);
|
||||||
|
|
||||||
|
if (op->type == GISI_MESSAGE_TYPE_RESP && op->notify != NULL) {
|
||||||
|
GIsiMessage msg = {
|
||||||
|
.error = ESHUTDOWN,
|
||||||
|
};
|
||||||
|
|
||||||
|
pending_dispatch(op, &msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
pending_destroy(op, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void g_isi_pending_set_owner(GIsiPending *op, gpointer owner)
|
||||||
|
{
|
||||||
|
if (op == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
op->owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
void g_isi_remove_pending_by_owner(GIsiModem *modem, uint8_t resource,
|
||||||
|
gpointer owner)
|
||||||
|
{
|
||||||
|
GIsiServiceMux *mux;
|
||||||
|
GSList *l;
|
||||||
|
GSList *next;
|
||||||
|
GIsiPending *op;
|
||||||
|
GSList *owned = NULL;
|
||||||
|
|
||||||
|
mux = service_get(modem, resource);
|
||||||
|
if (mux == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (l = mux->pending; l != NULL; l = next) {
|
||||||
|
next = l->next;
|
||||||
|
op = l->data;
|
||||||
|
|
||||||
|
if (op->owner != owner)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mux->pending = g_slist_remove_link(mux->pending, l);
|
||||||
|
|
||||||
|
l->next = owned;
|
||||||
|
owned = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (l = owned; l != NULL; l = l->next) {
|
||||||
|
op = l->data;
|
||||||
|
|
||||||
|
foreach_destroy(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_slist_free(owned);
|
||||||
|
}
|
||||||
|
|
||||||
GIsiPending *g_isi_ntf_subscribe(GIsiModem *modem, uint8_t resource,
|
GIsiPending *g_isi_ntf_subscribe(GIsiModem *modem, uint8_t resource,
|
||||||
uint8_t msgid, GIsiNotifyFunc notify,
|
uint8_t msgid, GIsiNotifyFunc notify,
|
||||||
void *data, GDestroyNotify destroy)
|
void *data, GDestroyNotify destroy)
|
||||||
|
|
|
@ -109,7 +109,10 @@ int g_isi_response_vsend(GIsiModem *modem, const GIsiMessage *req,
|
||||||
|
|
||||||
GIsiPending *g_isi_pending_from_msg(const GIsiMessage *msg);
|
GIsiPending *g_isi_pending_from_msg(const GIsiMessage *msg);
|
||||||
|
|
||||||
void g_isi_pending_remove(GIsiPending *operation);
|
void g_isi_pending_remove(GIsiPending *op);
|
||||||
|
void g_isi_pending_set_owner(GIsiPending *op, gpointer owner);
|
||||||
|
void g_isi_remove_pending_by_owner(GIsiModem *modem, uint8_t resource,
|
||||||
|
gpointer owner);
|
||||||
|
|
||||||
GIsiPending *g_isi_resource_ping(GIsiModem *modem, uint8_t resource,
|
GIsiPending *g_isi_resource_ping(GIsiModem *modem, uint8_t resource,
|
||||||
GIsiNotifyFunc notify, void *data,
|
GIsiNotifyFunc notify, void *data,
|
||||||
|
|
|
@ -32,30 +32,12 @@
|
||||||
|
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
struct pending_data {
|
|
||||||
GIsiServer *server;
|
|
||||||
GIsiNotifyFunc notify;
|
|
||||||
void *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GIsiServer {
|
struct _GIsiServer {
|
||||||
GIsiModem *modem;
|
GIsiModem *modem;
|
||||||
GIsiVersion version;
|
GIsiVersion version;
|
||||||
uint8_t resource;
|
uint8_t resource;
|
||||||
GSList *pending;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pending_notify(const GIsiMessage *msg, void *data)
|
|
||||||
{
|
|
||||||
struct pending_data *pd = data;
|
|
||||||
|
|
||||||
if (pd == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (pd->notify != NULL)
|
|
||||||
pd->notify(msg, pd->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t g_isi_server_resource(GIsiServer *server)
|
uint8_t g_isi_server_resource(GIsiServer *server)
|
||||||
{
|
{
|
||||||
return server != NULL ? server->resource : 0;
|
return server != NULL ? server->resource : 0;
|
||||||
|
@ -87,30 +69,17 @@ GIsiServer *g_isi_server_create(GIsiModem *modem, uint8_t resource,
|
||||||
|
|
||||||
server->resource = resource;
|
server->resource = resource;
|
||||||
server->modem = modem;
|
server->modem = modem;
|
||||||
server->pending = NULL;
|
|
||||||
|
|
||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void foreach_destroy(gpointer value, gpointer user)
|
|
||||||
{
|
|
||||||
GIsiPending *op = value;
|
|
||||||
GIsiServer *server = user;
|
|
||||||
|
|
||||||
if (op == NULL || server == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
server->pending = g_slist_remove(server->pending, op);
|
|
||||||
g_isi_pending_remove(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
void g_isi_server_destroy(GIsiServer *server)
|
void g_isi_server_destroy(GIsiServer *server)
|
||||||
{
|
{
|
||||||
if (server == NULL)
|
if (server == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_slist_foreach(server->pending, foreach_destroy, server);
|
g_isi_remove_pending_by_owner(server->modem, server->resource, server);
|
||||||
g_slist_free(server->pending);
|
|
||||||
g_free(server);
|
g_free(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,47 +101,15 @@ int g_isi_server_vsend(GIsiServer *server, const GIsiMessage *req,
|
||||||
return g_isi_response_vsend(server->modem, req, iov, iovlen);
|
return g_isi_response_vsend(server->modem, req, iov, iovlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pending_data *pending_data_create(GIsiServer *server,
|
|
||||||
GIsiNotifyFunc notify,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
struct pending_data *pd;
|
|
||||||
|
|
||||||
if (server == NULL) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pd = g_try_new0(struct pending_data, 1);
|
|
||||||
if (pd == NULL) {
|
|
||||||
errno = ENOMEM;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pd->server = server;
|
|
||||||
pd->notify = notify;
|
|
||||||
pd->data = data;
|
|
||||||
|
|
||||||
return pd;
|
|
||||||
}
|
|
||||||
|
|
||||||
GIsiPending *g_isi_server_handle(GIsiServer *server, uint8_t type,
|
GIsiPending *g_isi_server_handle(GIsiServer *server, uint8_t type,
|
||||||
GIsiNotifyFunc notify, void *data)
|
GIsiNotifyFunc notify, void *data)
|
||||||
{
|
{
|
||||||
struct pending_data *pd;
|
|
||||||
GIsiPending *op;
|
GIsiPending *op;
|
||||||
|
|
||||||
pd = pending_data_create(server, notify, data);
|
|
||||||
if (pd == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
op = g_isi_service_bind(server->modem, server->resource, type,
|
op = g_isi_service_bind(server->modem, server->resource, type,
|
||||||
pending_notify, pd, g_free);
|
notify, data, NULL);
|
||||||
if (op == NULL) {
|
|
||||||
g_free(pd);
|
g_isi_pending_set_owner(op, server);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
server->pending = g_slist_append(server->pending, op);
|
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue