1 /* -*- mode: C; indent-tabs-mode: t; tab-width: 8; c-basic-offset: 2; -*- */
4 * This file is part of Seed, the GObject Introspection<->Javascript bindings.
6 * Seed is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation, either version 3 of
9 * the License, or (at your option) any later version.
10 * Seed is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with Seed. If not, see <http://www.gnu.org/licenses/>.
17 * Copyright (C) Robert Carr 2009 <carrr@rpi.edu>
20 #include <seed-module.h>
26 SeedObject namespace_ref;
29 typedef struct _pipe_priv {
34 void pipe_finalize(SeedObject pipeobj)
36 pipe_priv *priv = seed_object_get_private(pipeobj);
37 g_io_channel_unref(priv->read);
38 g_io_channel_unref(priv->write);
42 SeedObject seed_construct_pipe(SeedContext ctx,
43 SeedObject constructor,
44 size_t argument_count,
45 const SeedValue arguments[],
46 SeedException * exception)
48 SeedObject jsone, jstwo, jsret;
50 pipe_priv *priv_one, *priv_two;
52 CHECK_ARG_COUNT("multiprocessing.pipe constructor", 0);
56 perror("Pipe failed. Make me a javascript exception");
57 return seed_make_null(ctx);
61 perror("Pipe failed. Make me a javascript exception");
62 return seed_make_null(ctx);
65 priv_one = g_new0(pipe_priv, 1);
66 priv_two = g_new0(pipe_priv, 1);
68 priv_one->read = g_io_channel_unix_new(fd1[0]);
69 priv_one->write = g_io_channel_unix_new(fd2[1]);
70 priv_two->read = g_io_channel_unix_new(fd2[0]);
71 priv_two->write = g_io_channel_unix_new(fd1[1]);
73 g_io_channel_set_close_on_unref(priv_one->read, TRUE);
74 g_io_channel_set_close_on_unref(priv_one->write, TRUE);
75 g_io_channel_set_close_on_unref(priv_two->read, TRUE);
76 g_io_channel_set_close_on_unref(priv_two->write, TRUE);
78 jsret = seed_make_object(ctx, 0, 0);
79 jsone = seed_make_object(ctx, pipe_class, priv_one);
80 jstwo = seed_make_object(ctx, pipe_class, priv_two);
82 seed_object_set_property_at_index(ctx, jsret, 0, jsone, exception);
83 seed_object_set_property_at_index(ctx, jsret, 1, jstwo, exception);
88 #define GET_CHANNEL pipe_priv * priv = \
89 seed_object_get_private(this_object)
91 SeedValue seed_pipe_read(SeedContext ctx,
93 SeedObject this_object,
94 size_t argument_count,
95 const SeedValue arguments[], SeedException * exception)
101 CHECK_ARG_COUNT("multiprocessing.pipe.read", 0);
103 g_io_channel_read_line(priv->read, &read, 0, 0, 0);
104 ret = seed_value_from_string(ctx, read, exception);
110 typedef struct _marshal_privates {
116 static gboolean gio_marshal_func(GIOChannel * source,
117 GIOCondition condition, gpointer data)
119 SeedGlobalContext ctx = seed_context_create(eng->group, 0);
120 SeedValue jscondition = seed_value_from_long(ctx, (glong) condition, 0);
121 SeedValue args[3], ret;
122 marshal_privates *priv = (marshal_privates *) data;
125 args[0] = priv->source;
126 args[1] = jscondition;
127 args[2] = priv->user_data;
129 ret = seed_object_call(ctx, priv->function, 0, 3, args, 0);
131 bret = seed_value_to_boolean(ctx, ret, 0);
132 seed_context_unref(ctx);
140 SeedValue seed_pipe_write(SeedContext ctx,
142 SeedObject this_object,
143 size_t argument_count,
144 const SeedValue arguments[],
145 SeedException * exception)
152 CHECK_ARG_COUNT("multiprocessing.pipe.write", 1);
154 data = seed_value_to_string(ctx, arguments[0], exception);
155 g_io_channel_write_chars(priv->write, data, -1, &written, 0);
156 g_io_channel_write_chars(priv->write, &eol, 1, 0, 0);
157 g_io_channel_flush(priv->write, 0);
159 return seed_value_from_int(ctx, written, exception);
162 SeedValue seed_pipe_add_watch(SeedContext ctx,
164 SeedObject this_object,
165 size_t argument_count,
166 const SeedValue arguments[],
167 SeedException * exception)
171 marshal_privates *mpriv = g_malloc0(sizeof(marshal_privates));
172 glong condition = seed_value_to_long(ctx, arguments[0], exception);
174 mpriv->function = arguments[1];
175 mpriv->source = this_object;
176 mpriv->user_data = argument_count == 3 ? arguments[2] : seed_make_null(ctx);
178 g_io_add_watch(priv->read, condition, gio_marshal_func, mpriv);
180 return seed_value_from_boolean(ctx, TRUE, exception);
183 seed_static_function pipe_funcs[] = {
184 {"read", seed_pipe_read, 0},
185 {"write", seed_pipe_write, 0},
186 {"add_watch", seed_pipe_add_watch, 0},
191 seed_module_init(SeedEngine * local_eng)
193 SeedObject pipe_constructor;
194 seed_class_definition pipe_class_def = seed_empty_class;
197 namespace_ref = seed_make_object(eng->context, 0, 0);
199 pipe_class_def.class_name = "Pipe";
200 pipe_class_def.static_functions = pipe_funcs;
201 pipe_class_def.finalize = pipe_finalize;
203 pipe_class = seed_create_class(&pipe_class_def);
205 pipe_constructor = seed_make_constructor(eng->context,
206 0, seed_construct_pipe);
208 seed_object_set_property(eng->context,
209 namespace_ref, "Pipe", pipe_constructor);
211 return namespace_ref;