~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to io/channel.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#include "qemu/osdep.h"
22
22
#include "io/channel.h"
23
23
#include "qapi/error.h"
24
 
#include "qemu/coroutine.h"
 
24
#include "qemu/main-loop.h"
25
25
 
26
26
bool qio_channel_has_feature(QIOChannel *ioc,
27
27
                             QIOChannelFeature feature)
154
154
}
155
155
 
156
156
 
 
157
void qio_channel_set_aio_fd_handler(QIOChannel *ioc,
 
158
                                    AioContext *ctx,
 
159
                                    IOHandler *io_read,
 
160
                                    IOHandler *io_write,
 
161
                                    void *opaque)
 
162
{
 
163
    QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc);
 
164
 
 
165
    klass->io_set_aio_fd_handler(ioc, ctx, io_read, io_write, opaque);
 
166
}
 
167
 
157
168
guint qio_channel_add_watch(QIOChannel *ioc,
158
169
                            GIOCondition condition,
159
170
                            QIOChannelFunc func,
227
238
}
228
239
 
229
240
 
230
 
typedef struct QIOChannelYieldData QIOChannelYieldData;
231
 
struct QIOChannelYieldData {
232
 
    QIOChannel *ioc;
233
 
    Coroutine *co;
234
 
};
235
 
 
236
 
 
237
 
static gboolean qio_channel_yield_enter(QIOChannel *ioc,
238
 
                                        GIOCondition condition,
239
 
                                        gpointer opaque)
240
 
{
241
 
    QIOChannelYieldData *data = opaque;
242
 
    qemu_coroutine_enter(data->co);
243
 
    return FALSE;
244
 
}
245
 
 
 
241
static void qio_channel_set_aio_fd_handlers(QIOChannel *ioc);
 
242
 
 
243
static void qio_channel_restart_read(void *opaque)
 
244
{
 
245
    QIOChannel *ioc = opaque;
 
246
    Coroutine *co = ioc->read_coroutine;
 
247
 
 
248
    ioc->read_coroutine = NULL;
 
249
    qio_channel_set_aio_fd_handlers(ioc);
 
250
    aio_co_wake(co);
 
251
}
 
252
 
 
253
static void qio_channel_restart_write(void *opaque)
 
254
{
 
255
    QIOChannel *ioc = opaque;
 
256
    Coroutine *co = ioc->write_coroutine;
 
257
 
 
258
    ioc->write_coroutine = NULL;
 
259
    qio_channel_set_aio_fd_handlers(ioc);
 
260
    aio_co_wake(co);
 
261
}
 
262
 
 
263
static void qio_channel_set_aio_fd_handlers(QIOChannel *ioc)
 
264
{
 
265
    IOHandler *rd_handler = NULL, *wr_handler = NULL;
 
266
    AioContext *ctx;
 
267
 
 
268
    if (ioc->read_coroutine) {
 
269
        rd_handler = qio_channel_restart_read;
 
270
    }
 
271
    if (ioc->write_coroutine) {
 
272
        wr_handler = qio_channel_restart_write;
 
273
    }
 
274
 
 
275
    ctx = ioc->ctx ? ioc->ctx : iohandler_get_aio_context();
 
276
    qio_channel_set_aio_fd_handler(ioc, ctx, rd_handler, wr_handler, ioc);
 
277
}
 
278
 
 
279
void qio_channel_attach_aio_context(QIOChannel *ioc,
 
280
                                    AioContext *ctx)
 
281
{
 
282
    AioContext *old_ctx;
 
283
    if (ioc->ctx == ctx) {
 
284
        return;
 
285
    }
 
286
 
 
287
    old_ctx = ioc->ctx ? ioc->ctx : iohandler_get_aio_context();
 
288
    qio_channel_set_aio_fd_handler(ioc, old_ctx, NULL, NULL, NULL);
 
289
    ioc->ctx = ctx;
 
290
    qio_channel_set_aio_fd_handlers(ioc);
 
291
}
 
292
 
 
293
void qio_channel_detach_aio_context(QIOChannel *ioc)
 
294
{
 
295
    ioc->read_coroutine = NULL;
 
296
    ioc->write_coroutine = NULL;
 
297
    qio_channel_set_aio_fd_handlers(ioc);
 
298
    ioc->ctx = NULL;
 
299
}
246
300
 
247
301
void coroutine_fn qio_channel_yield(QIOChannel *ioc,
248
302
                                    GIOCondition condition)
249
303
{
250
 
    QIOChannelYieldData data;
251
 
 
252
304
    assert(qemu_in_coroutine());
253
 
    data.ioc = ioc;
254
 
    data.co = qemu_coroutine_self();
255
 
    qio_channel_add_watch(ioc,
256
 
                          condition,
257
 
                          qio_channel_yield_enter,
258
 
                          &data,
259
 
                          NULL);
 
305
    if (condition == G_IO_IN) {
 
306
        assert(!ioc->read_coroutine);
 
307
        ioc->read_coroutine = qemu_coroutine_self();
 
308
    } else if (condition == G_IO_OUT) {
 
309
        assert(!ioc->write_coroutine);
 
310
        ioc->write_coroutine = qemu_coroutine_self();
 
311
    } else {
 
312
        abort();
 
313
    }
 
314
    qio_channel_set_aio_fd_handlers(ioc);
260
315
    qemu_coroutine_yield();
261
316
}
262
317