예제 #1
0
/* TYPICALLY CALLED FROM ANOTHER THREAD */
void
hio_output_stream_write(HioOutputStream *stream,
                        HrtBuffer       *locked_buffer)
{
    g_return_if_fail(hrt_buffer_is_locked(locked_buffer));

    if (hrt_buffer_get_length(locked_buffer) == 0)
        return;

    if (hio_output_stream_is_closed(stream))
        return;

    g_mutex_lock(stream->buffers_lock);
    /* note, we still want to buffer stuff if fd == -1 since that just
     * means we aren't being asked to write yet. But on error, discard
     * anything that gets written.
     */
    if (g_atomic_int_get(&stream->errored) == 0) {
        /* we could set stream->errored right here after we just
         * checked we haven't. However in that case, the
         * drop_all_buffers() just after we set stream->errored will
         * have to block for buffers_lock and only then drop them, so
         * it should drop this one we're pushing.
         */
        hrt_buffer_ref(locked_buffer);
        g_queue_push_tail(&stream->buffers,
                          locked_buffer);
    }
    g_mutex_unlock(stream->buffers_lock);

    /* add write watcher if necessary. */
    check_write_watcher(stream);
}
예제 #2
0
static void
test_stream_with_error(OutputTestFixture *fixture,
                       const void        *data)
{
    HioOutputStream *stream;

    g_assert(fixture->chain_task == NULL);

    close(fixture->read_fd); /* should error the writes */

    stream = hio_output_stream_new(fixture->stream_tasks[0]);
    hio_output_stream_set_fd(stream, fixture->write_fd);

    hrt_task_add_immediate(fixture->write_tasks[0],
                           on_write_stream_task,
                           write_task_data_new(stream, fixture->stream_descs),
                           write_task_data_free);

    /* run main loop to collect the tasks */
    g_main_loop_run(fixture->loop);

    /* if the stream is zero-length we'll never try to write and never get an error */
    g_assert(fixture->stream_descs->length == 0 ||
             hio_output_stream_got_error(stream));
    g_assert(hio_output_stream_is_done(stream));
    g_assert(hio_output_stream_is_closed(stream));

    g_object_unref(stream);

    /* so we don't close it again in teardown */
    fixture->read_fd = -1;
}
예제 #3
0
static void
test_stream_with_initial_error(OutputTestFixture *fixture,
                               const void        *data)
{
    HioOutputStream *stream;

    g_assert(fixture->chain_task == NULL);

    /* error before we even set an fd on it */
    stream = hio_output_stream_new(fixture->stream_tasks[0]);
    hio_output_stream_error(stream);

    hrt_task_add_immediate(fixture->write_tasks[0],
                           on_write_stream_task,
                           write_task_data_new(stream, fixture->stream_descs),
                           write_task_data_free);

    /* run main loop to collect the tasks */
    g_main_loop_run(fixture->loop);

    g_assert(hio_output_stream_got_error(stream));
    g_assert(hio_output_stream_is_done(stream));
    g_assert(hio_output_stream_is_closed(stream));

    g_object_unref(stream);
}
예제 #4
0
static void
test_stream(OutputTestFixture *fixture,
            const void        *data)
{
    HioOutputStream *stream;

    g_assert(fixture->chain_task == NULL);

    stream = hio_output_stream_new(fixture->stream_tasks[0]);
    hio_output_stream_set_fd(stream, fixture->write_fd);

    hrt_task_add_immediate(fixture->write_tasks[0],
                           on_write_stream_task,
                           write_task_data_new(stream, fixture->stream_descs),
                           write_task_data_free);

    read_and_verify_stream(fixture->read_fd, fixture->stream_descs);

    /* run main loop to collect the task */
    g_main_loop_run(fixture->loop);

    g_assert(!hio_output_stream_got_error(stream));
    g_assert(hio_output_stream_is_done(stream));
    g_assert(hio_output_stream_is_closed(stream));

    g_object_unref(stream);
}
예제 #5
0
/* CALLED FROM ANY THREAD */
gboolean
hio_output_stream_is_done(HioOutputStream *stream)
{
    gboolean done;

    g_mutex_lock(stream->buffers_lock);
    done = hio_output_stream_is_closed(stream) &&
        (g_queue_get_length(&stream->buffers) == 0 ||
         hio_output_stream_got_error(stream));
    g_mutex_unlock(stream->buffers_lock);

    return done;
}