qio: store gsources for net listeners

Originally we were storing the GSources tag IDs.  That'll be not enough
if we are going to support non-default gcontext for QIO code.  Switch to
GSources without changing anything real.  Now we still always pass in
NULL, which means the default gcontext.

Signed-off-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Peter Xu 2018-03-05 14:43:21 +08:00 committed by Daniel P. Berrangé
parent 315409c711
commit 938c8b79e5
2 changed files with 59 additions and 27 deletions

View File

@ -53,7 +53,7 @@ struct QIONetListener {
char *name; char *name;
QIOChannelSocket **sioc; QIOChannelSocket **sioc;
gulong *io_tag; GSource **io_source;
size_t nsioc; size_t nsioc;
bool connected; bool connected;
@ -119,6 +119,26 @@ int qio_net_listener_open_sync(QIONetListener *listener,
void qio_net_listener_add(QIONetListener *listener, void qio_net_listener_add(QIONetListener *listener,
QIOChannelSocket *sioc); QIOChannelSocket *sioc);
/**
* qio_net_listener_set_client_func_full:
* @listener: the network listener object
* @func: the callback function
* @data: opaque data to pass to @func
* @notify: callback to free @data
* @context: the context that the sources will be bound to. If %NULL,
* the default context will be used.
*
* Register @func to be invoked whenever a new client
* connects to the listener. @func will be invoked
* passing in the QIOChannelSocket instance for the
* client.
*/
void qio_net_listener_set_client_func_full(QIONetListener *listener,
QIONetListenerClientFunc func,
gpointer data,
GDestroyNotify notify,
GMainContext *context);
/** /**
* qio_net_listener_set_client_func: * qio_net_listener_set_client_func:
* @listener: the network listener object * @listener: the network listener object
@ -126,10 +146,8 @@ void qio_net_listener_add(QIONetListener *listener,
* @data: opaque data to pass to @func * @data: opaque data to pass to @func
* @notify: callback to free @data * @notify: callback to free @data
* *
* Register @func to be invoked whenever a new client * Wrapper of qio_net_listener_set_client_func_full(), only that the
* connects to the listener. @func will be invoked * sources will always be bound to default main context.
* passing in the QIOChannelSocket instance for the
* client.
*/ */
void qio_net_listener_set_client_func(QIONetListener *listener, void qio_net_listener_set_client_func(QIONetListener *listener,
QIONetListenerClientFunc func, QIONetListenerClientFunc func,

View File

@ -118,29 +118,32 @@ void qio_net_listener_add(QIONetListener *listener,
listener->sioc = g_renew(QIOChannelSocket *, listener->sioc, listener->sioc = g_renew(QIOChannelSocket *, listener->sioc,
listener->nsioc + 1); listener->nsioc + 1);
listener->io_tag = g_renew(gulong, listener->io_tag, listener->nsioc + 1); listener->io_source = g_renew(typeof(listener->io_source[0]),
listener->io_source,
listener->nsioc + 1);
listener->sioc[listener->nsioc] = sioc; listener->sioc[listener->nsioc] = sioc;
listener->io_tag[listener->nsioc] = 0; listener->io_source[listener->nsioc] = NULL;
object_ref(OBJECT(sioc)); object_ref(OBJECT(sioc));
listener->connected = true; listener->connected = true;
if (listener->io_func != NULL) { if (listener->io_func != NULL) {
object_ref(OBJECT(listener)); object_ref(OBJECT(listener));
listener->io_tag[listener->nsioc] = qio_channel_add_watch( listener->io_source[listener->nsioc] = qio_channel_add_watch_source(
QIO_CHANNEL(listener->sioc[listener->nsioc]), G_IO_IN, QIO_CHANNEL(listener->sioc[listener->nsioc]), G_IO_IN,
qio_net_listener_channel_func, qio_net_listener_channel_func,
listener, (GDestroyNotify)object_unref); listener, (GDestroyNotify)object_unref, NULL);
} }
listener->nsioc++; listener->nsioc++;
} }
void qio_net_listener_set_client_func(QIONetListener *listener, void qio_net_listener_set_client_func_full(QIONetListener *listener,
QIONetListenerClientFunc func, QIONetListenerClientFunc func,
gpointer data, gpointer data,
GDestroyNotify notify) GDestroyNotify notify,
GMainContext *context)
{ {
size_t i; size_t i;
@ -152,23 +155,32 @@ void qio_net_listener_set_client_func(QIONetListener *listener,
listener->io_notify = notify; listener->io_notify = notify;
for (i = 0; i < listener->nsioc; i++) { for (i = 0; i < listener->nsioc; i++) {
if (listener->io_tag[i]) { if (listener->io_source[i]) {
g_source_remove(listener->io_tag[i]); g_source_destroy(listener->io_source[i]);
listener->io_tag[i] = 0; g_source_unref(listener->io_source[i]);
listener->io_source[i] = NULL;
} }
} }
if (listener->io_func != NULL) { if (listener->io_func != NULL) {
for (i = 0; i < listener->nsioc; i++) { for (i = 0; i < listener->nsioc; i++) {
object_ref(OBJECT(listener)); object_ref(OBJECT(listener));
listener->io_tag[i] = qio_channel_add_watch( listener->io_source[i] = qio_channel_add_watch_source(
QIO_CHANNEL(listener->sioc[i]), G_IO_IN, QIO_CHANNEL(listener->sioc[i]), G_IO_IN,
qio_net_listener_channel_func, qio_net_listener_channel_func,
listener, (GDestroyNotify)object_unref); listener, (GDestroyNotify)object_unref, context);
} }
} }
} }
void qio_net_listener_set_client_func(QIONetListener *listener,
QIONetListenerClientFunc func,
gpointer data,
GDestroyNotify notify)
{
qio_net_listener_set_client_func_full(listener, func, data,
notify, NULL);
}
struct QIONetListenerClientWaitData { struct QIONetListenerClientWaitData {
QIOChannelSocket *sioc; QIOChannelSocket *sioc;
@ -211,9 +223,10 @@ QIOChannelSocket *qio_net_listener_wait_client(QIONetListener *listener)
size_t i; size_t i;
for (i = 0; i < listener->nsioc; i++) { for (i = 0; i < listener->nsioc; i++) {
if (listener->io_tag[i]) { if (listener->io_source[i]) {
g_source_remove(listener->io_tag[i]); g_source_destroy(listener->io_source[i]);
listener->io_tag[i] = 0; g_source_unref(listener->io_source[i]);
listener->io_source[i] = NULL;
} }
} }
@ -241,10 +254,10 @@ QIOChannelSocket *qio_net_listener_wait_client(QIONetListener *listener)
if (listener->io_func != NULL) { if (listener->io_func != NULL) {
for (i = 0; i < listener->nsioc; i++) { for (i = 0; i < listener->nsioc; i++) {
object_ref(OBJECT(listener)); object_ref(OBJECT(listener));
listener->io_tag[i] = qio_channel_add_watch( listener->io_source[i] = qio_channel_add_watch_source(
QIO_CHANNEL(listener->sioc[i]), G_IO_IN, QIO_CHANNEL(listener->sioc[i]), G_IO_IN,
qio_net_listener_channel_func, qio_net_listener_channel_func,
listener, (GDestroyNotify)object_unref); listener, (GDestroyNotify)object_unref, NULL);
} }
} }
@ -260,9 +273,10 @@ void qio_net_listener_disconnect(QIONetListener *listener)
} }
for (i = 0; i < listener->nsioc; i++) { for (i = 0; i < listener->nsioc; i++) {
if (listener->io_tag[i]) { if (listener->io_source[i]) {
g_source_remove(listener->io_tag[i]); g_source_destroy(listener->io_source[i]);
listener->io_tag[i] = 0; g_source_unref(listener->io_source[i]);
listener->io_source[i] = NULL;
} }
qio_channel_close(QIO_CHANNEL(listener->sioc[i]), NULL); qio_channel_close(QIO_CHANNEL(listener->sioc[i]), NULL);
} }
@ -285,7 +299,7 @@ static void qio_net_listener_finalize(Object *obj)
for (i = 0; i < listener->nsioc; i++) { for (i = 0; i < listener->nsioc; i++) {
object_unref(OBJECT(listener->sioc[i])); object_unref(OBJECT(listener->sioc[i]));
} }
g_free(listener->io_tag); g_free(listener->io_source);
g_free(listener->sioc); g_free(listener->sioc);
g_free(listener->name); g_free(listener->name);
} }