erlix 0.5.0a

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/ruby
2
+ #-*- ruby -*-
3
+ # project : erlix
4
+ # author : kdr2
5
+ #
6
+
7
+ findei=File.join(File.dirname(__FILE__),"findei.erl")
8
+ File.chmod(0755,findei)
9
+ ei_dir=`#{findei}`.chomp
10
+ src_dir=File.join(File.dirname(__FILE__),"src")
11
+ mkmf=File.join(File.dirname(__FILE__),"extconf.rb")
12
+ cmd=[
13
+ "ruby #{mkmf}",
14
+ "--with-ei-dir=#{ei_dir}",
15
+ "--with-cflags=\"-std=c99\"",
16
+ "--with-ldflags=\"-lei -lerl_interface -lpthread\"",
17
+ "--srcdir=#{src_dir}"].join(" ")
18
+
19
+ env=[
20
+ "--with-ei-dir=#{ei_dir}",
21
+ "--with-cflags=\"-std=c99\"",
22
+ "--with-ldflags=\"-lei -lerl_interface -lpthread\"",
23
+ "--srcdir=#{src_dir}"].join(" ")
24
+ puts cmd
25
+ puts `#{cmd}`
26
+
27
+
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/ruby
2
+ #-*- ruby -*-
3
+ # project : erlix
4
+ # author : kdr2
5
+ #
6
+
7
+ findei=File.join(File.dirname(__FILE__),"findei.erl")
8
+ File.chmod(0755,findei)
9
+ ei_dir=`#{findei}`.chomp
10
+ src_dir=File.join(File.dirname(__FILE__),"src")
11
+ mkmf=File.join(File.dirname(__FILE__),"extconf.rb")
12
+ cmd=[
13
+ "ruby #{mkmf}",
14
+ "--with-ei-dir=#{ei_dir}",
15
+ "--with-cflags=\"-std=c99\"",
16
+ "--with-ldflags=\"-lei -lerl_interface -lpthread\"",
17
+ "--srcdir=#{src_dir}"].join(" ")
18
+
19
+ env=[
20
+ "--with-ei-dir=#{ei_dir}",
21
+ "--with-cflags=\"-std=c99\"",
22
+ "--with-ldflags=\"-lei -lerl_interface -lpthread\"",
23
+ "--srcdir=#{src_dir}"].join(" ")
24
+ puts cmd
25
+ puts `#{cmd}`
26
+
27
+
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # project : erlix
4
+ # author : kdr2
5
+ #
6
+
7
+ require "mkmf"
8
+
9
+ dir_config("ei")
10
+
11
+ if have_library("ei","erl_init") and
12
+ have_library("erl_interface","erl_init")
13
+ then
14
+ create_makefile("erlix")
15
+ else
16
+ puts "error: erl_interface not found!"
17
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env escript
2
+ %%% Author : KDr2
3
+ %%% Find the location of erl_interface.
4
+
5
+ main(_) ->
6
+ io:format("~s~n", [code:lib_dir(erl_interface)]).
@@ -0,0 +1,30 @@
1
+ /*
2
+ * project : erlix
3
+ * author : kdr2
4
+ *
5
+ */
6
+ #include <stdlib.h>
7
+
8
+ #include "erlix_term.h"
9
+
10
+
11
+
12
+
13
+ void Init_erlix(){
14
+ VALUE mod_erlix;
15
+ mod_erlix=rb_define_module("Erlix");
16
+ erl_init(NULL,0);
17
+ init_erlix_term(mod_erlix);
18
+ init_erlix_int(mod_erlix);
19
+ init_erlix_uint(mod_erlix);
20
+ init_erlix_float(mod_erlix);
21
+ init_erlix_pid(mod_erlix);
22
+ init_erlix_ref(mod_erlix);
23
+ init_erlix_atom(mod_erlix);
24
+ init_erlix_list(mod_erlix);
25
+ init_erlix_node(mod_erlix);
26
+ init_erlix_tuple(mod_erlix);
27
+ init_erlix_binary(mod_erlix);
28
+ init_erlix_message(mod_erlix);
29
+ init_erlix_connection(mod_erlix);
30
+ }
@@ -0,0 +1,62 @@
1
+ /* -*- c-*-
2
+ *
3
+ * project : erlix
4
+ * author : KDr2
5
+ *
6
+ */
7
+
8
+ #include "erlix_term.h"
9
+
10
+ VALUE erlix_cErlixAtom;
11
+
12
+ VALUE erlix_atom_alloc(VALUE klass){
13
+ ErlixTerm* atom;
14
+ VALUE obj;
15
+ atom=new_erlix_term();
16
+ atom->type=TYPE_ATOM;
17
+ obj=Data_Wrap_Struct(klass,0,free_erlix_term,atom);
18
+ return obj;
19
+ }
20
+
21
+ static VALUE erlix_atom_init(VALUE self,VALUE string){
22
+ ErlixTerm* atom;
23
+ VALUE str=StringValue(string);
24
+ Data_Get_Struct(self,ErlixTerm,atom);
25
+ atom->term=erl_mk_atom(RSTRING_PTR(str));
26
+ return self;
27
+ }
28
+
29
+
30
+ static VALUE erlix_atom_size(VALUE self){
31
+ ErlixTerm *atom;
32
+ int l;
33
+ Data_Get_Struct(self,ErlixTerm,atom);
34
+ l=ERL_ATOM_SIZE(atom->term);
35
+ return INT2FIX(l);
36
+ }
37
+
38
+ static VALUE erlix_atom_inspect(VALUE self){
39
+ VALUE ret=rb_str_new2("#<Erlix::Atom:");
40
+ ID concat=rb_intern("concat");
41
+ rb_funcall(ret,concat,1,rb_funcall(self,rb_intern("to_s"),0));
42
+ rb_funcall(ret,concat,1,rb_str_new2(">"));
43
+ return ret;
44
+ }
45
+
46
+ static VALUE erlix_atom_etype(VALUE self){
47
+ return rb_str_new2("atom");
48
+ }
49
+
50
+ void init_erlix_atom(VALUE erlix){
51
+ erlix_cErlixAtom=rb_define_class_under(erlix,"Atom",rb_cObject);
52
+
53
+ rb_define_alloc_func(erlix_cErlixAtom,erlix_atom_alloc);
54
+ rb_define_method(erlix_cErlixAtom,"initialize",erlix_atom_init,1);
55
+ rb_define_method(erlix_cErlixAtom,"size",erlix_atom_size,0);
56
+ rb_define_method(erlix_cErlixAtom,"etype",erlix_atom_etype,0);
57
+ rb_define_method(erlix_cErlixAtom,"inspect",erlix_atom_inspect,0);
58
+
59
+ rb_include_module(erlix_cErlixAtom,erlix_mErlixTerm);
60
+ }
61
+
62
+
@@ -0,0 +1,67 @@
1
+ /*
2
+ * project : erlix
3
+ * author : kdr2
4
+ *
5
+ */
6
+
7
+ #include "erlix_term.h"
8
+
9
+ VALUE erlix_cErlixBinary;
10
+
11
+ VALUE erlix_binary_alloc(VALUE klass){
12
+ ErlixTerm* binary;
13
+ VALUE obj;
14
+ binary=new_erlix_term();
15
+ binary->type=TYPE_BINARY;
16
+ obj=Data_Wrap_Struct(klass,0,free_erlix_term,binary);
17
+ return obj;
18
+ }
19
+
20
+ static VALUE erlix_binary_init(VALUE self,VALUE string){
21
+ ErlixTerm* binary;
22
+ VALUE str=StringValue(string);
23
+ Data_Get_Struct(self,ErlixTerm,binary);
24
+ //TODO length limit
25
+ binary->term=erl_mk_binary(RSTRING_PTR(str),(uint32_t)RSTRING_LEN(str));
26
+ return self;
27
+ }
28
+
29
+
30
+ static VALUE erlix_binary_data(VALUE self){
31
+ ErlixTerm* binary;
32
+ Data_Get_Struct(self,ErlixTerm,binary);
33
+ return rb_str_new(ERL_BIN_PTR(binary->term),ERL_BIN_SIZE(binary->term));
34
+ }
35
+
36
+ static VALUE erlix_binary_size(VALUE self){
37
+ ErlixTerm *binary;
38
+ int l;
39
+ Data_Get_Struct(self,ErlixTerm,binary);
40
+ l=ERL_BIN_SIZE(binary->term);
41
+ return INT2FIX(l);
42
+ }
43
+
44
+ static VALUE erlix_binary_inspect(VALUE self){
45
+ VALUE ret=rb_str_new2("#<Erlix::Binary:");
46
+ ID concat=rb_intern("concat");
47
+ rb_funcall(ret,concat,1,rb_funcall(self,rb_intern("to_s"),0));
48
+ rb_funcall(ret,concat,1,rb_str_new2(">"));
49
+ return ret;
50
+ }
51
+
52
+ static VALUE erlix_binary_etype(VALUE self){
53
+ return rb_str_new2("binary");
54
+ }
55
+
56
+ void init_erlix_binary(VALUE erlix){
57
+ erlix_cErlixBinary=rb_define_class_under(erlix, "Binary",rb_cObject);
58
+
59
+ rb_define_alloc_func(erlix_cErlixBinary,erlix_binary_alloc);
60
+ rb_define_method(erlix_cErlixBinary,"initialize",erlix_binary_init,1);
61
+ rb_define_method(erlix_cErlixBinary,"data",erlix_binary_data,0);
62
+ rb_define_method(erlix_cErlixBinary,"size",erlix_binary_size,0);
63
+ rb_define_method(erlix_cErlixBinary,"inspect",erlix_binary_inspect,0);
64
+ rb_define_method(erlix_cErlixBinary,"etype",erlix_binary_etype,0);
65
+
66
+ rb_include_module(erlix_cErlixBinary,erlix_mErlixTerm);
67
+ }
@@ -0,0 +1,247 @@
1
+ /*
2
+ * project : erlix
3
+ * author : kdr2
4
+ *
5
+ */
6
+
7
+ #include <unistd.h>
8
+ #include <stdlib.h>
9
+
10
+ #include "erlix_term.h"
11
+ #include "erlix_node.h"
12
+ #include "erlix_connection.h"
13
+
14
+ extern ErlixNode* erlix_node;
15
+ extern VALUE erlix_cErlixMessage;
16
+
17
+ VALUE erlix_cErlixConnection;
18
+
19
+ ErlixConnection* new_erlix_connection(){
20
+ ErlixConnection* ret=(ErlixConnection*)malloc(sizeof(ErlixConnection));
21
+ ret->status=0;
22
+ return ret;
23
+ }
24
+
25
+ void free_erlix_connection(void *econ){
26
+ ErlixConnection* ep=econ;
27
+ ERLIX_CONNECTION_DEAD(ep);
28
+ erl_close_connection(ep->sock_fd);
29
+ free(ep);
30
+ }
31
+
32
+ VALUE erlix_connection_alloc(VALUE klass){
33
+ ErlixConnection* ec=new_erlix_connection();
34
+ VALUE obj;
35
+ obj=Data_Wrap_Struct(klass,0,free_erlix_connection,ec);
36
+ return obj;
37
+ }
38
+
39
+ static VALUE erlix_connection_init(VALUE self,VALUE pnode){
40
+ VALUE node;
41
+ int sockfd;
42
+ ErlixConnection *conn;
43
+
44
+ if(erlix_node==NULL){
45
+ rb_raise(rb_eException,"call Erlix::Node.init(name,cookie) first please!");
46
+ return Qnil;
47
+ }
48
+ node=StringValue(pnode);
49
+ if((sockfd = erl_connect(RSTRING_PTR(node)))<0){
50
+ rb_raise(rb_eException,"erl_connect failed");
51
+ return Qnil;
52
+ }
53
+
54
+ Data_Get_Struct(self,ErlixConnection,conn);
55
+ conn->peer_node=rb_str_new2(RSTRING_PTR(node));
56
+ conn->sock_fd=sockfd;
57
+ ERLIX_CONNECTION_BORN(conn);
58
+ return self;
59
+ }
60
+
61
+
62
+ static VALUE erlix_connection_init_copy(VALUE copy,VALUE orig){
63
+ ErlixConnection *tcopy,*tsrc;
64
+
65
+ if(copy==orig)return copy;
66
+ if(TYPE(orig)!=T_DATA||RDATA(orig)->dfree!=(RUBY_DATA_FUNC)free_erlix_connection){
67
+ rb_raise(rb_eTypeError,"wrong argument type!");
68
+ }
69
+
70
+ Data_Get_Struct(copy,ErlixConnection,tcopy);
71
+ Data_Get_Struct(orig,ErlixConnection,tsrc);
72
+
73
+ if(!ERLIX_CONNECTION_ALIVE(tsrc)){
74
+ rb_raise(rb_eException,"the connection has been disconnected!");
75
+ return Qnil;
76
+ }
77
+
78
+ tcopy->status=tsrc->status;
79
+ tcopy->peer_node=rb_str_new2(RSTRING_PTR(tsrc->peer_node));
80
+ tcopy->sock_fd=tsrc->sock_fd;
81
+
82
+ return copy;
83
+ }
84
+
85
+
86
+ static VALUE erlix_connection_to_str(VALUE self);
87
+
88
+ //peer node name
89
+ static VALUE erlix_connection_peer(VALUE self){
90
+ ErlixConnection *con;
91
+ Data_Get_Struct(self,ErlixConnection,con);
92
+ if(!ERLIX_CONNECTION_ALIVE(con)){
93
+ rb_raise(rb_eException,"the connection has been disconnected!");
94
+ return Qnil;
95
+ }
96
+ return con->peer_node;
97
+ }
98
+
99
+ static VALUE erlix_connection_etype(VALUE self){
100
+ return rb_str_new2("erlix_connection");
101
+ }
102
+
103
+ static VALUE erlix_connection_mkpid(VALUE self);
104
+
105
+ static VALUE erlix_connection_send(VALUE self,VALUE pid,VALUE term){
106
+ ErlixConnection *con;
107
+ ErlixTerm * ep;
108
+
109
+ if(!IS_ETERM(term)){
110
+ rb_raise(rb_eTypeError,"wrong argument type,the data is not an ErlixTerm!");
111
+ return Qnil;
112
+ }
113
+ Data_Get_Struct(self,ErlixConnection,con);
114
+ Data_Get_Struct(term,ErlixTerm,ep);
115
+ if(!ERLIX_CONNECTION_ALIVE(con)){
116
+ rb_raise(rb_eException,"the connection has been disconnected!");
117
+ return Qnil;
118
+ }
119
+ if(TYPE(pid)==T_STRING){
120
+ if(erl_reg_send(con->sock_fd,RSTRING_PTR(pid),ep->term)==1){
121
+ return term;
122
+ }else if(erl_errno==EIO){
123
+ ERLIX_CONNECTION_DEAD(con);
124
+ rb_raise(rb_eException,"IO Error!");
125
+ return Qnil;
126
+ }
127
+ }
128
+ return Qnil;
129
+ }
130
+
131
+ extern int rb_io_wait_readable(int);
132
+
133
+ static VALUE erlix_connection_recv(VALUE self){
134
+ ErlixConnection *con;
135
+ ErlMessage emsg;
136
+
137
+ Data_Get_Struct(self,ErlixConnection,con);
138
+
139
+ if(!ERLIX_CONNECTION_ALIVE(con)){
140
+ rb_raise(rb_eException,"the connection has been disconnected!");
141
+ return Qnil;
142
+ }
143
+ for(;;){
144
+ //bugfixed! for 1.8.7 thread block!
145
+ if(rb_io_wait_readable(con->sock_fd)!=Qtrue){
146
+ rb_thread_wait_fd(con->sock_fd);
147
+ }
148
+ int ret;
149
+ VALUE m;
150
+ ErlMessage *newm;
151
+
152
+ ret=erl_receive_msg(con->sock_fd,NULL,0,&emsg);
153
+ if (ret == ERL_MSG) {
154
+ m=erlix_message_alloc(erlix_cErlixMessage);
155
+ Data_Get_Struct(m,ErlMessage,newm);
156
+ newm->type=emsg.type;
157
+ if(emsg.type==ERL_SEND){
158
+ newm->msg=erl_copy_term(emsg.msg);
159
+ newm->to=erl_copy_term(emsg.to);
160
+ }else if(emsg.type==ERL_REG_SEND){
161
+ newm->msg=erl_copy_term(emsg.msg);
162
+ newm->from=erl_copy_term(emsg.from);
163
+ }else if(emsg.type==ERL_LINK ||emsg.type==ERL_UNLINK){
164
+ newm->from=erl_copy_term(emsg.from);
165
+ newm->to=erl_copy_term(emsg.to);
166
+ }else if(emsg.type==ERL_EXIT){
167
+ newm->msg=erl_copy_term(emsg.msg);
168
+ newm->from=erl_copy_term(emsg.from);
169
+ newm->to=erl_copy_term(emsg.to);
170
+ }
171
+ memcpy(newm->to_name,emsg.to_name,MAXREGLEN);
172
+ return m;
173
+ }else if(ret == ERL_TICK){
174
+ continue;
175
+ }else{
176
+ rb_raise(rb_eException,"receive error!");
177
+ return Qnil;
178
+ }
179
+ }
180
+ return Qnil;
181
+ }
182
+
183
+ static VALUE erlix_connection_rpc(VALUE self,VALUE module,VALUE func,VALUE args){
184
+
185
+ VALUE m;
186
+ VALUE f;
187
+ ErlixTerm* a;
188
+ ErlixConnection *con;
189
+ ETERM *result;
190
+
191
+ m=StringValue(module);
192
+ f=StringValue(func);
193
+ if(!IS_ETERM(args)){
194
+ rb_raise(rb_eTypeError,"wrong argument type,the data is not an ErlixList!");
195
+ return Qnil;
196
+ }
197
+ Data_Get_Struct(args,ErlixTerm,a);
198
+ if(a->type!=TYPE_LIST){
199
+ rb_raise(rb_eTypeError,"wrong argument type,the data is not an ErlixList!");
200
+ return Qnil;
201
+ }
202
+ Data_Get_Struct(self,ErlixConnection,con);
203
+ result=erl_rpc(con->sock_fd, RSTRING_PTR(m),RSTRING_PTR(f), a->term);
204
+ if(result==NULL){
205
+ if(erl_errno==ENOMEM){
206
+ rb_raise(rb_eException,"rpc error: no memory");
207
+ }else if(erl_errno==EIO){
208
+ rb_raise(rb_eException,"rpc error: I/O error");
209
+ }else if(erl_errno==ETIMEDOUT){
210
+ rb_raise(rb_eException,"rpc error: timeout");
211
+ }else if(erl_errno==EAGAIN){
212
+ rb_raise(rb_eException,"rpc error: Temporary error, Try again");
213
+ }
214
+ return Qnil;
215
+ }
216
+ return erlix_term(result);
217
+ }
218
+
219
+ static VALUE erlix_connection_close(VALUE self){
220
+ ErlixConnection *con;
221
+ Data_Get_Struct(self,ErlixConnection,con);
222
+ ERLIX_CONNECTION_DEAD(con);
223
+ close(con->sock_fd);
224
+ return Qtrue;
225
+ }
226
+
227
+ static VALUE erlix_connection_isclosed(VALUE self){
228
+ ErlixConnection *con;
229
+ Data_Get_Struct(self,ErlixConnection,con);
230
+ if(ERLIX_CONNECTION_ALIVE(con)){
231
+ return Qfalse;
232
+ }
233
+ return Qtrue;
234
+ }
235
+
236
+ void init_erlix_connection(VALUE erlix){
237
+ erlix_cErlixConnection=rb_define_class_under(erlix,"Connection",rb_cObject);
238
+ rb_define_alloc_func(erlix_cErlixConnection,erlix_connection_alloc);
239
+ rb_define_method(erlix_cErlixConnection,"initialize",erlix_connection_init,1);
240
+ rb_define_method(erlix_cErlixConnection,"initialize_copy",erlix_connection_init_copy,1);
241
+ rb_define_method(erlix_cErlixConnection,"peer",erlix_connection_peer,0);
242
+ rb_define_method(erlix_cErlixConnection,"esend",erlix_connection_send,2);
243
+ rb_define_method(erlix_cErlixConnection,"erecv",erlix_connection_recv,0);
244
+ rb_define_method(erlix_cErlixConnection,"rpc",erlix_connection_rpc,3);
245
+ rb_define_method(erlix_cErlixConnection,"close",erlix_connection_close,0);
246
+ rb_define_method(erlix_cErlixConnection,"closed?",erlix_connection_isclosed,0);
247
+ }