[svn:parrot] r39761 - in branches/io_cleanups: src/pmc t/pmc

whiteknight at svn.parrot.org whiteknight at svn.parrot.org
Thu Jun 25 00:37:47 UTC 2009


Author: whiteknight
Date: Thu Jun 25 00:37:46 2009
New Revision: 39761
URL: https://trac.parrot.org/parrot/changeset/39761

Log:
[io_cleanups] Apply patch from Infinoid++ to add initial implementation of Pipe and PipeHandle PMC types. However, breaks all the packfile tests because we added new PMC types. Need to regenerate the packfiles. Help me Infinoid Kenobi, you're my only hope

Added:
   branches/io_cleanups/src/pmc/pipe.pmc
   branches/io_cleanups/src/pmc/pipehandle.pmc
   branches/io_cleanups/t/pmc/pipe.t

Added: branches/io_cleanups/src/pmc/pipe.pmc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/io_cleanups/src/pmc/pipe.pmc	Thu Jun 25 00:37:46 2009	(r39761)
@@ -0,0 +1,167 @@
+/*
+Copyright (C) 2008, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/pmc/pipe.pmc - Pipe PMC
+
+=head1 DESCRIPTION
+
+The Pipe PMC creates two connected IO handles for IPC purposes.  Each instance
+is a container for a matched pair of PipeHandle objects, one read-only and one
+write-only.  Data written to the writer is readable from the reader.
+
+=head2 Vtable Functions
+
+=over 4
+
+=cut
+
+*/
+
+#include "pmc_pipehandle.h"
+
+pmclass Pipe {
+    ATTR PMC *r; /* Readable IO handle */
+    ATTR PMC *w; /* Writable IO handle */
+
+/*
+
+=item C<void init()>
+
+Create a new pipe.
+
+=cut
+
+*/
+
+    VTABLE void init() {
+        PIOHANDLE reader, writer;
+        Parrot_Pipe_attributes *attrs =
+                mem_allocate_zeroed_typed(Parrot_Pipe_attributes);
+
+        PMC_data(SELF)      = attrs;
+        if(PIO_PIPE(interp, &reader, &writer) < 0) {
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+                            "Cannot open pipe");
+        }
+        attrs->r = pmc_new(interp, enum_class_PipeHandle);
+        attrs->w = pmc_new(interp, enum_class_PipeHandle);
+        if(!attrs->r || !attrs->w) {
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+                            "Cannot create PipeHandle PMCs");
+        }
+        PARROT_PIPEHANDLE(attrs->r)->os_handle = reader;
+        PARROT_PIPEHANDLE(attrs->w)->os_handle = writer;
+        PARROT_PIPEHANDLE(attrs->r)->reader = 1;
+        PARROT_PIPEHANDLE(attrs->w)->writer = 1;
+
+        PObj_custom_mark_SET(SELF);
+    }
+
+
+/*
+
+=item C<PMC *clone()>
+
+Create a copy of the pipe container object.  The PipeHandle objects it contains
+are *not* cloned.
+
+=cut
+
+*/
+
+    VTABLE PMC *clone() {
+        PMC * copy = SUPER();
+        Parrot_Pipe_attributes * const old_struct  = PARROT_PIPE(SELF);
+        Parrot_Pipe_attributes * const data_struct = PARROT_PIPE(copy);
+
+        data_struct->r = old_struct->r;
+        data_struct->w = old_struct->w;
+
+        return SELF;
+    }
+
+
+/*
+
+=item C<void mark()>
+
+Mark active filehandle data as live.
+
+=cut
+
+*/
+
+    VTABLE void mark() {
+        Parrot_Pipe_attributes * const attrs = PARROT_PIPE(SELF);
+
+        if (attrs) {
+            if (attrs->r)
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)attrs->r);
+
+            if (attrs->w)
+                Parrot_gc_mark_PObj_alive(interp, (PObj *)attrs->w);
+        }
+    }
+
+
+/*
+
+=back
+
+=head2 Methods
+
+=over 4
+
+=item C<reader>
+
+Return the read-only PipeHandle object.
+
+=cut
+
+*/
+
+
+    METHOD reader() {
+        PMC *rv;
+        Parrot_Pipe_attributes * const attrs = PARROT_PIPE(SELF);
+        rv = attrs->r;
+        RETURN(PMC *rv);
+    }
+
+/*
+
+=item C<writer>
+
+Return the write-only PipeHandle object.
+
+=cut
+
+*/
+
+
+    METHOD writer() {
+        PMC *rv;
+        Parrot_Pipe_attributes * const attrs = PARROT_PIPE(SELF);
+        rv = attrs->w;
+        RETURN(PMC *rv);
+    }
+
+/*
+
+=back
+
+=cut
+
+*/
+
+} /* end pmclass */
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Added: branches/io_cleanups/src/pmc/pipehandle.pmc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/io_cleanups/src/pmc/pipehandle.pmc	Thu Jun 25 00:37:46 2009	(r39761)
@@ -0,0 +1,126 @@
+/*
+Copyright (C) 2008, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/pmc/pipehandle.pmc - PipeHandle PMC
+
+=head1 DESCRIPTION
+
+The PipeHandle PMC is an I/O handle used to access one endpoint of a Pipe pair.
+It is created by the Pipe PMC.
+
+This object may be read-only or write-only, depending on which side of the Pipe
+it is.
+
+=head2 Vtable Functions
+
+=over 4
+
+=cut
+
+*/
+
+#include "../src/io/io_private.h"
+
+pmclass PipeHandle extends Handle {
+    ATTR INTVAL reader;
+    ATTR INTVAL writer;
+
+/*
+
+=item C<void init()>
+
+Initializes a newly created Socket object.
+
+=cut
+
+*/
+
+    VTABLE void init() {
+        Parrot_PipeHandle_attributes *attrs =
+                mem_allocate_zeroed_typed(Parrot_PipeHandle_attributes);
+
+        PMC_data(SELF) = attrs;
+        attrs->reader  = 0;
+        attrs->writer  = 0;
+        attrs->os_handle = PIO_INVALID_HANDLE;
+
+        PObj_active_destroy_SET(SELF);
+    }
+
+
+/*
+
+=item C<PMC *clone()>
+
+Create a copy of the pipe handle.
+
+=cut
+
+*/
+
+    VTABLE PMC *clone() {
+        PMC * copy = SUPER();
+        Parrot_PipeHandle_attributes * const old_struct = PARROT_PIPEHANDLE(SELF);
+        Parrot_PipeHandle_attributes * const data_struct = PARROT_PIPEHANDLE(copy);
+
+        data_struct->reader = old_struct->reader;
+        data_struct->writer = old_struct->writer;
+
+        return SELF;
+    }
+
+/*
+
+=item C<void destroy()>
+
+Free structures.
+
+=cut
+
+*/
+    VTABLE void destroy() {
+        if (PARROT_PIPEHANDLE(SELF)) {
+            Parrot_PipeHandle_attributes *data_struct = PARROT_PIPEHANDLE(SELF);
+
+            if(data_struct->os_handle != PIO_INVALID_HANDLE)
+                Parrot_io_close_piohandle(interp, data_struct->os_handle);
+            data_struct->os_handle = PIO_INVALID_HANDLE;
+        }
+    }
+
+
+/*
+
+=item C<INTVAL get_bool()>
+
+Returns whether the Pipe is currently open.
+
+=cut
+
+*/
+
+    VTABLE INTVAL get_bool() {
+        Parrot_PipeHandle_attributes * const attrs = PARROT_PIPEHANDLE(SELF);
+        return (attrs->os_handle != PIO_INVALID_HANDLE);
+    }
+
+
+/*
+
+=back
+
+=cut
+
+*/
+
+} /* end pmclass */
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Added: branches/io_cleanups/t/pmc/pipe.t
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/io_cleanups/t/pmc/pipe.t	Thu Jun 25 00:37:46 2009	(r39761)
@@ -0,0 +1,71 @@
+#! parrot
+# Copyright (C) 2009, Parrot Foundation.
+# $Id$
+
+=head1 NAME
+
+t/pmc/pipe.t - test the Pipe and PipeHandle PMCs
+
+
+=head1 SYNOPSIS
+
+    % prove t/pmc/pipe.t
+
+=head1 DESCRIPTION
+
+Tests the Pipe and PipeHandle PMCs.  Creates some pipes, tries some basic I/O.
+
+=cut
+
+.sub main :main
+.include 'test_more.pir'
+    plan(3)
+    test_new()
+    test_reader_writer_methods()
+#    test_reading_writing() # spawn a thread to write to the pipe, read the data
+#    test_blocking_io()     # same thing, but with a delay in the middle
+.end
+
+.sub test_new
+    .local pmc pipe
+    .local string tmp
+    pipe = new ['Pipe']
+    tmp = typeof pipe
+    is(tmp, 'Pipe', 'typeof(Pipe) == "Pipe"')
+.end
+
+.sub test_reader_writer_methods
+    .local pmc pipe, reader, writer
+    .local string tmp
+    pipe = new ['Pipe']
+    reader = pipe.'reader'()
+    writer = pipe.'writer'()
+    tmp = typeof reader
+    is(tmp, 'PipeHandle', 'typeof(reader) == "PipeHandle"')
+    tmp = typeof writer
+    is(tmp, 'PipeHandle', 'typeof(writer) == "PipeHandle"')
+.end
+
+.sub test_reading_writing
+    .local pmc pipe, reader, writer, writer_thread, writer_thread_func
+    .local string teststr, readstr
+
+    pipe = new ['Pipe']
+    reader = pipe.'reader'()
+    writer = pipe.'writer'()
+    writer_thread_func = get_global 'test_reading_writing_writer'
+    writer_thread = new ['ParrotThread']
+    teststr = 'This is a test string.'
+    writer_thread.'run_clone'(writer_thread_func, writer, teststr)
+    readstr = reader.'read'()
+    writer_thread.'join'()
+    is(teststr, readstr, 'read string matches')
+.end
+
+.sub test_reading_writing_writer
+    .param pmc writer
+    .param string teststr
+    writer.'write'(teststr)
+    writer.'close'() # do this explicitly to force a write-buffer flush
+    returncc         # return, killing the thread
+.end


More information about the parrot-commits mailing list