Annotation of OpenXM_contrib2/asir2018/io/tcpf.c, Revision 1.3
1.1 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not limited to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as academic, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as permitted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
1.3 ! ohara 47: * $OpenXM: OpenXM_contrib2/asir2018/io/tcpf.c,v 1.2 2018/09/28 08:20:29 noro Exp $
1.1 noro 48: */
49: #include "ca.h"
50: #include "parse.h"
51: #include "com.h"
52: #include <signal.h>
53: #include <string.h>
1.3 ! ohara 54: #include <stdlib.h>
! 55: #if !defined(VISUAL) && !defined(__MINGW32__)
! 56: #include <unistd.h>
1.1 noro 57: #include <sys/types.h>
58: #include <sys/wait.h>
59: #include <pwd.h>
1.3 ! ohara 60: #endif
1.1 noro 61:
62: #include "ox.h"
63:
64: #if defined(VISUAL) || defined(__MINGW32__)
65: #include <winsock2.h>
66: #include <process.h>
67: #endif
68:
69: #define INIT_TAB_SIZ 64
70: #define OX_XTERM "ox_xterm"
71:
72: #if !defined(_PA_RISC1_1)
73: #define RSH "rsh"
74: #else
75: #define RSH "remsh"
76: #endif
77:
78: static struct m_c {
79: int m,c,af_unix;
80: } *m_c_tab;
81:
82: static int m_c_i,m_c_s;
83: int I_am_server;
84:
85: extern int little_endian;
86:
87: #if defined(MPI)
88: extern int mpi_nprocs;
89: #define valid_mctab_index(ind)\
90: if((ind)<0||(ind)>=mpi_nprocs){error("invalid server id");}
91: #define check_valid_mctab_index(ind)\
92: if((ind)<0||(ind)>=mpi_nprocs){(ind)=-1;}
93: #else
94: #define valid_mctab_index(ind)\
95: if((ind)<I_am_server||(ind)>=m_c_i||\
96: ((m_c_tab[ind].m<0)&&(m_c_tab[ind].c<0))){error("invalid server id");}
97: #define check_valid_mctab_index(ind)\
98: if((ind)<I_am_server||(ind)>=m_c_i||\
99: ((m_c_tab[ind].m<0)&&(m_c_tab[ind].c<0))){(ind)=-1;}
100: #endif
101:
102: struct IOFP iofp_102[MAXIOFP];
103: int nserver_102;
104: int myrank_102;
105:
106: int register_102(int s,int rank, int is_master);
107:
108: int register_server();
109: int get_mcindex(int);
110:
111: void Pox_send_raw_cmo(), Pox_recv_raw_cmo();
112:
113: void Pox_launch(),Pox_launch_nox();
114: void Pox_launch_generic();
115: void Pox_shutdown();
116:
117: void Pox_rpc(),Pox_cmo_rpc(),Pox_reset(),Pox_intr(),Pox_sync(),Pox_select();
118:
119: void Pox_push_local(),Pox_push_cmo(),Pox_push_vl(),Pox_push_cmd();
120:
121: void Pox_pop_local(),Pox_pop_cmo();
122: void Pox_pop0_local(),Pox_pop0_cmo();
123: void Pox_pop_string(),Pox_pop0_string();
124: void Pox_get(),Pox_pops();
125:
126: void Pox_execute_function(),Pox_execute_string();
127: void Pox_setname(), Pox_evalname();
128: void Pox_flush();
129: void Pgenerate_port(),Ptry_bind_listen(),Ptry_connect(),Ptry_accept();
130: void Pregister_server();
131: void Pox_get_serverinfo();
132: void Pox_mpi_myid(), Pox_mpi_nprocs();
133: void Pox_tcp_accept_102(),Pox_tcp_connect_102();
134: void Pox_send_102(),Pox_recv_102();
135: void Pox_set_rank_102();
136: void Pox_get_rank_102();
137: void Pox_reset_102();
138: void Pox_bcast_102();
139: void Pox_reduce_102();
140:
141: void ox_launch_generic();
142:
143: pointer bevalf();
144:
145: struct ftab tcp_tab[] = {
146: {"ox_send_raw_cmo",Pox_send_raw_cmo,2},
147: {"ox_recv_raw_cmo",Pox_recv_raw_cmo,1},
148: {"ox_get_serverinfo",Pox_get_serverinfo,-1},
149: {"generate_port",Pgenerate_port,-1},
150:
151: /* from master to client */
152: {"ox_set_rank_102",Pox_set_rank_102,3},
153: {"ox_tcp_accept_102",Pox_tcp_accept_102,3},
154: {"ox_tcp_connect_102",Pox_tcp_connect_102,4},
155: {"ox_reset_102",Pox_reset_102,1},
156:
157: {"ox_get_rank_102",Pox_get_rank_102,0},
158: {"ox_send_102",Pox_send_102,2},
159: {"ox_recv_102",Pox_recv_102,1},
160: {"ox_bcast_102",Pox_bcast_102,-2},
161: {"ox_reduce_102",Pox_reduce_102,-3},
162:
163: {"try_bind_listen",Ptry_bind_listen,1},
164: {"try_connect",Ptry_connect,2},
165: {"try_accept",Ptry_accept,2},
166: {"register_server",Pregister_server,4},
167: {"ox_flush",Pox_flush,1},
168: {"ox_launch",Pox_launch,-3},
169: {"ox_launch_nox",Pox_launch_nox,-3},
170: {"ox_launch_generic",Pox_launch_generic,7},
171: {"ox_shutdown",Pox_shutdown,1},
172:
173: {"ox_rpc",Pox_rpc,-99999999},
174: {"ox_cmo_rpc",Pox_cmo_rpc,-99999999},
175:
176: {"ox_sync",Pox_sync,1},
177: #if defined(MPI)
178: {"ox_mpi_myid",Pox_mpi_myid,0},
179: {"ox_mpi_nprocs",Pox_mpi_nprocs,0},
180: #endif
181: #if !defined(MPI)
182: {"ox_reset",Pox_reset,-2},
183: {"ox_intr",Pox_intr,1},
184: {"ox_select",Pox_select,-2},
185: #endif
186:
187: {"ox_pop_string",Pox_pop_string,1},
188: {"ox_pop0_string",Pox_pop0_string,1},
189: {"ox_pop_local",Pox_pop_local,1},
190: {"ox_pop0_local",Pox_pop0_local,1},
191: {"ox_pop_cmo",Pox_pop_cmo,1},
192: {"ox_pop0_cmo",Pox_pop0_cmo,1},
193: {"ox_get",Pox_get,-1},
194: {"ox_pops",Pox_pops,-2},
195:
196: {"ox_push_vl",Pox_push_vl,1},
197: {"ox_push_local",Pox_push_local,-99999999},
198: {"ox_push_cmo",Pox_push_cmo,-99999999},
199: {"ox_push_cmd",Pox_push_cmd,2},
200:
201: {"ox_setname",Pox_setname,2},
202: {"ox_evalname",Pox_evalname,2},
203:
204: {"ox_execute_string",Pox_execute_string,2},
205: {"ox_execute_function",Pox_execute_function,3},
206:
207: {0,0,0},
208: };
209:
210: extern struct IOFP iofp[];
211: extern MATHCAP my_mathcap;
212: extern int ox_exchange_mathcap;
213:
214: Obj asir_pop_one();
215: void asir_push_one(Obj);
216:
217: #if defined(MPI)
218: extern int mpi_myid, mpi_nprocs;
219:
220: void Pox_mpi_myid(Z *rp)
221: {
1.2 noro 222: STOZ(mpi_myid,*rp);
1.1 noro 223: }
224:
225: void Pox_mpi_nprocs(Z *rp)
226: {
1.2 noro 227: STOZ(mpi_nprocs,*rp);
1.1 noro 228: }
229: #endif
230:
231: void Pox_get_serverinfo(NODE arg,LIST *rp)
232: {
233: int i,c;
234: Z s_id;
235: NODE t,n0,n;
236: LIST list,l;
237:
238: if ( !arg ) {
239: for ( i = I_am_server?1:0, n0 = 0; i < m_c_i; i++ )
240: if ( (m_c_tab[i].m>=0) || (m_c_tab[i].c>=0) ) {
241: c = m_c_tab[i].c;
242: ox_get_serverinfo(c,&list);
1.2 noro 243: STOZ(i,s_id);
1.1 noro 244: t = mknode(2,s_id,list);
245: MKLIST(l,t);
246: NEXTNODE(n0,n);
247: BDY(n) = (pointer)l;
248: }
249: if ( n0 )
250: NEXT(n) = 0;
251: MKLIST(*rp,n0);
252: } else {
1.2 noro 253: i = ZTOS((Q)ARG0(arg));
1.1 noro 254: if ( i >= 0 && i < m_c_i && ((m_c_tab[i].m>=0) || (m_c_tab[i].c>=0)) )
255: ox_get_serverinfo(m_c_tab[i].c,rp);
256: else {
257: MKLIST(*rp,0);
258: }
259: }
260: }
261:
262: /*
263: if noarg or arg[0]==0 then use IP socket and return a port number
264: else use UNIX socket and return a string which represents a path name
265: */
266:
267: void Pgenerate_port(NODE arg,Obj *rp)
268: {
269: char port_str[BUFSIZ];
270: int port;
271: char *s;
272: STRING str;
273: Z q;
274:
275: if ( !arg || !ARG0(arg) ) {
276: generate_port(0,port_str);
277: port = atoi(port_str);
1.2 noro 278: STOZ(port,q);
1.1 noro 279: *rp = (Obj)q;
280: } else {
281: generate_port(1,port_str);
282: s = (char *)MALLOC(strlen((char *)port_str)+1);
283: strcpy(s,port_str);
284: MKSTR(str,s);
285: *rp = (Obj)str;
286: }
287: }
288:
289: void Pox_reset_102(NODE arg,Z *rp)
290: {
291: int s;
1.2 noro 292: int index = ZTOS((Q)ARG0(arg));
1.1 noro 293:
294: valid_mctab_index(index);
295: s = m_c_tab[index].c;
296: ox_send_cmd(s,SM_reset_102);
297: ox_flush_stream_force(s);
298: *rp = 0;
299: }
300:
301: void Pox_get_rank_102(LIST *rp)
302: {
303: Z n,r;
304: NODE node;
305:
1.2 noro 306: STOZ(nserver_102,n);
307: STOZ(myrank_102,r);
1.1 noro 308: node = mknode(2,n,r);
309: MKLIST(*rp,node);
310: }
311:
312: void Pox_set_rank_102(NODE arg,Z *rp)
313: {
314: Z nserver,rank;
315: int s;
1.2 noro 316: int index = ZTOS((Q)ARG0(arg));
1.1 noro 317:
318: valid_mctab_index(index);
319: s = m_c_tab[index].c;
320: nserver = (Z)ARG1(arg);
321: rank = (Z)ARG2(arg);
322: ox_send_data(s,nserver);
323: ox_send_data(s,rank);
324: ox_send_cmd(s,SM_set_rank_102);
325: ox_flush_stream_force(s);
326: *rp = 0;
327: }
328:
329: /* ox_tcp_accept_102(server,port,rank) */
330:
331: void Pox_tcp_accept_102(NODE arg,Z *rp)
332: {
333: int s;
1.2 noro 334: int index = ZTOS((Q)ARG0(arg));
1.1 noro 335:
336: valid_mctab_index(index);
337: s = m_c_tab[index].c;
338:
339: ox_send_data(s,ARG1(arg));
340: ox_send_data(s,ARG2(arg));
341: ox_send_cmd(s,SM_tcp_accept_102);
342: ox_flush_stream_force(s);
343: *rp = 0;
344: }
345:
346: /*
347: ox_tcp_connect_102(server,host,port,rank)
348: */
349:
350: void Pox_tcp_connect_102(NODE arg,Z *rp)
351: {
352: int s;
1.2 noro 353: int index = ZTOS((Q)ARG0(arg));
1.1 noro 354:
355: valid_mctab_index(index);
356: s = m_c_tab[index].c;
357:
358: ox_send_data(s,ARG1(arg));
359: ox_send_data(s,ARG2(arg));
360: ox_send_data(s,ARG3(arg));
361: ox_send_cmd(s,SM_tcp_connect_102);
362: ox_flush_stream_force(s);
363: *rp = 0;
364: }
365:
366: /*
367: try_bind_listen(port)
368: */
369:
370: void Ptry_bind_listen(NODE arg,Z *rp)
371: {
372: char port_str[BUFSIZ];
373: int port,s,use_unix;
374:
375: if ( IS_CYGWIN || !ARG0(arg) || NUM(ARG0(arg)) ) {
1.2 noro 376: port = ZTOS((Q)ARG0(arg));
1.1 noro 377: sprintf(port_str,"%d",port);
378: use_unix = 0;
379: } else {
380: strcpy(port_str,BDY((STRING)ARG0(arg)));
381: use_unix = 1;
382: }
383: s = try_bind_listen(use_unix,port_str);
1.2 noro 384: STOZ(s,*rp);
1.1 noro 385: }
386:
387: /*
388: try_connect(host,port)
389: */
390:
391: void Ptry_connect(NODE arg,Z *rp)
392: {
393: char port_str[BUFSIZ];
394: char *host;
395: int port,s,use_unix;
396:
397: if ( IS_CYGWIN || !ARG1(arg) || NUM(ARG1(arg)) ) {
1.2 noro 398: port = ZTOS((Q)ARG1(arg));
1.1 noro 399: sprintf(port_str,"%d",port);
400: use_unix = 0;
401: } else {
402: strcpy(port_str,BDY((STRING)ARG1(arg)));
403: use_unix = 1;
404: }
405: host = BDY((STRING)ARG0(arg));
406: s = try_connect(use_unix,host,port_str);
1.2 noro 407: STOZ(s,*rp);
1.1 noro 408: }
409:
410: /*
411: try_accept(sock,port)
412: */
413:
414: void Ptry_accept(NODE arg,Z *rp)
415: {
416: int use_unix,s;
417:
418: if ( IS_CYGWIN || !ARG1(arg) || NUM(ARG1(arg)) )
419: use_unix = 0;
420: else
421: use_unix = 1;
1.2 noro 422: s = try_accept(use_unix,ZTOS((Q)ARG0(arg)));
423: STOZ(s,*rp);
1.1 noro 424: }
425:
426: /*
427: register_server(cs,cport,ss,sport)
428: */
429:
430: void Pregister_server(NODE arg,Z *rp)
431: {
432: int cs,ss,cn,sn,ind,use_unix,id;
433: char cport_str[BUFSIZ],sport_str[BUFSIZ];
434: Obj obj;
435: MATHCAP server_mathcap;
436:
1.2 noro 437: cs = ZTOS((Q)ARG0(arg));
438: ss = ZTOS((Q)ARG2(arg));
1.1 noro 439: if ( IS_CYGWIN || !ARG1(arg) || NUM(ARG1(arg)) ) {
1.2 noro 440: sprintf(cport_str,"%d",ZTOS((Q)ARG1(arg)));
1.1 noro 441: use_unix = 0;
442: } else {
443: strcpy(cport_str,BDY((STRING)ARG1(arg)));
444: use_unix = 1;
445: }
446: if ( !ARG3(arg) || NUM(ARG3(arg)) ) {
447: if ( use_unix )
448: error("register_server : the protocol should conincide for two sockets");
1.2 noro 449: sprintf(sport_str,"%d",ZTOS((Q)ARG3(arg)));
1.1 noro 450: } else {
451: if ( !use_unix )
452: error("register_server : the protocol should conincide for two sockets");
453: strcpy(sport_str,BDY((STRING)ARG3(arg)));
454: }
455:
456: /* client mode */
457: cn = get_iofp(cs,cport_str,0);
458: sn = get_iofp(ss,sport_str,0);
459: /* get_iofp returns -1 if the laucher could not spawn the server */
460: if ( sn < 0 ) {
461: /* we should terminate the launcher */
462: ox_send_cmd(cn,SM_shutdown); ox_flush_stream_force(cn);
1.2 noro 463: STOZ(-1,*rp);
1.1 noro 464: return;
465: }
466:
467: /* register server to the server list */
468: ind = register_server(use_unix,cn,sn,-1);
469:
470: if ( ox_exchange_mathcap ) {
471: /* request remote mathcap */
472: ox_send_cmd(sn,SM_mathcap);
473: ox_send_cmd(sn,SM_popCMO);
474: ox_flush_stream_force(sn);
475: ox_recv(sn,&id,&obj); server_mathcap = (MATHCAP)obj;
476: store_remote_mathcap(sn,server_mathcap);
477:
478: /* send my mathcap */
479: create_my_mathcap("asir");
480: ox_send_data(sn,my_mathcap);
481: ox_send_cmd(sn,SM_setMathcap);
482: }
483: /* return the server id */
1.2 noro 484: STOZ(ind,*rp);
1.1 noro 485: }
486:
487: #if !defined(VISUAL) && !defined(__MINGW32__)
488: #include <sys/file.h>
489: #include <sys/types.h>
490: #include <sys/stat.h>
491: #include <pwd.h>
492:
493: static int find_executable(char *);
494: static int find_executable_main(char *);
495:
496: static int find_executable(char *com)
497: {
498: char *c,*s;
499: int len;
500: char dir[BUFSIZ],path[BUFSIZ];
501:
502: for ( s = (char *)getenv("PATH"); s; ) {
503: c = (char *)index(s,':');
504: if ( c ) {
505: len = c-s;
506: strncpy(dir,s,len); s = c+1; dir[len] = 0;
507: } else {
508: strcpy(dir,s); s = 0;
509: }
510: sprintf(path,"%s/%s",dir,com);
511: if ( find_executable_main(path) )
512: return 1;
513: }
514: return 0;
515: }
516:
517: static int find_executable_main(char *file)
518: {
519: struct stat buf;
520:
521: if ( stat(file,&buf) || (buf.st_mode & S_IFDIR) )
522: return 0;
523: if ( access(file,X_OK) )
524: return 0;
525: else
526: return 1;
527: }
528:
529: #endif
530: /*
531: ox_launch_generic(host,launcher,server,use_unix,use_ssh,use_x,conn_to_serv)
532:
533: Input
534: host: hostname on which servers run
535: launcher: path name of the launcher
536: server: path name of the server
537: use_unix: use UNIX domain socket if 1
538: use_ssh: use ssh if 1
539: use_x: use X11 facilities if 1
540: conn_to_serv: connect to server if 1
541: */
542:
543: void Pox_launch_generic(NODE arg,Z *rp)
544: {
545: int use_unix,use_ssh,use_x,conn_to_serv;
546: char *host,*launcher,*server;
547: Z ret;
548:
549: host = (arg&&ARG0(arg))?BDY((STRING)ARG0(arg)):0;
550: launcher = BDY((STRING)ARG1(arg));
551: server = BDY((STRING)ARG2(arg));
552: use_unix = !IS_CYGWIN && ARG3(arg) ? 1 : 0;
553: use_ssh = ARG4(arg) ? 1 : 0;
554: use_x = ARG5(arg) ? 1 : 0;
1.2 noro 555: conn_to_serv = ZTOS((Q)ARG6(arg));
1.1 noro 556: if ( !IS_CYGWIN && !host )
557: use_unix = 1;
558: ox_launch_generic(host,launcher,server,
559: use_unix,use_ssh,use_x,conn_to_serv,&ret);
560: *rp = ret;
561: }
562:
563: #if 0
564: void ox_launcher_101_generic(char *host,char *launcher,
565: int use_unix,int use_ssh,int use_x,int conn_to_serv,Z *rp)
566: {
567: int cs,cn,ind,id;
568: char control_port_str[BUFSIZ];
569: Obj obj;
570:
571: #if !defined(VISUAL) && !defined(__MINGW32__)
572: if ( use_unix && !find_executable("xterm") ) use_x = 0;
573: #endif
574: control_port_str[0] = 0;
575: do {
576: generate_port(use_unix,control_port_str);
577: if ( conn_to_serv ) {
578: spawn_server_101(host,launcher,
579: use_unix,use_ssh,use_x,conn_to_serv,
580: control_port_str);
581: cs = try_connect(use_unix,host,control_port_str);
582: } else {
583: cs = try_bind_listen(use_unix,control_port_str);
584: if ( cs < 0 ) continue;
585: spawn_laucher_101(host,launcher,
586: use_unix,use_ssh,use_x,conn_to_serv,
587: control_port_str);
588: cs = try_accept(use_unix,cs);
589: }
590: } while ( cs < 0 );
591:
592: /* client mode */
593: cn = get_iofp(cs,control_port_str,0);
594:
595: /* register server to the server list */
596: ind = register_server_101(use_unix,cn);
597:
1.2 noro 598: STOZ(ind,*rp);
1.1 noro 599: }
600: #endif
601:
602: void ox_launch_generic(char *host,char *launcher,char *server,
603: int use_unix,int use_ssh,int use_x,int conn_to_serv,Z *rp)
604: {
605: int cs,ss,cn,sn,ind,id;
606: char control_port_str[BUFSIZ];
607: char server_port_str[BUFSIZ];
608: Obj obj;
609: MATHCAP server_mathcap;
610: Z value;
611: char *key;
612: int fd=-1;
613: NODE opt,n0;
614:
615: if ( current_option ) {
616: for ( opt = current_option; opt; opt = NEXT(opt) ) {
617: n0 = BDY((LIST)BDY(opt));
618: key = BDY((STRING)BDY(n0));
619: value = (Z)BDY(NEXT(n0));
620: if ( !strcmp(key,"fd") && value ) {
1.2 noro 621: fd = ZTOS(value);
1.1 noro 622: break;
623: }
624: }
625: }
626: if (!available_mcindex(fd)) {
1.2 noro 627: STOZ(-1,*rp);
1.1 noro 628: return;
629: }
630: #if !defined(VISUAL) && !defined(__MINGW32__)
631: if ( use_unix && !find_executable("xterm") ) use_x = 0;
632: #endif
633: control_port_str[0] = 0;
634: server_port_str[0] = 0;
635: do {
636: generate_port(use_unix,control_port_str);
637: generate_port(use_unix,server_port_str);
638: if ( !conn_to_serv ) {
639: cs = try_bind_listen(use_unix,control_port_str);
640: if ( cs < 0 ) continue;
641: ss = try_bind_listen(use_unix,server_port_str);
642: if ( ss < 0 ) continue;
643: }
644: spawn_server(host,launcher,server,
645: use_unix,use_ssh,use_x,conn_to_serv,
646: control_port_str,server_port_str);
647: if ( conn_to_serv ) {
648: cs = try_connect(use_unix,host,control_port_str);
649: if ( cs < 0 ) continue;
650: ss = try_connect(use_unix,host,server_port_str);
651: if ( ss < 0 ) continue;
652: } else {
653: cs = try_accept(use_unix,cs);
654: if ( cs < 0 ) continue;
655: ss = try_accept(use_unix,ss);
656: if ( ss < 0 ) continue;
657: }
658: } while ( cs < 0 || ss < 0 );
659:
660: /* client mode */
661: cn = get_iofp(cs,control_port_str,0);
662: sn = get_iofp(ss,server_port_str,0);
663: /* get_iofp returns -1 if the laucher could not spawn the server */
664: if ( sn < 0 ) {
665: /* we should terminate the launcher */
666: ox_send_cmd(cn,SM_shutdown); ox_flush_stream_force(cn);
1.2 noro 667: STOZ(-1,*rp);
1.1 noro 668: return;
669: }
670:
671: /* register server to the server list */
672: ind = register_server(use_unix,cn,sn,fd);
673:
674: if ( ox_exchange_mathcap ) {
675: /* request remote mathcap */
676: ox_send_cmd(sn,SM_mathcap);
677: ox_send_cmd(sn,SM_popCMO);
678: ox_flush_stream_force(sn);
679: ox_recv(sn,&id,&obj); server_mathcap = (MATHCAP)obj;
680: store_remote_mathcap(sn,server_mathcap);
681:
682: /* send my mathcap */
683: create_my_mathcap("asir");
684: ox_send_data(sn,my_mathcap);
685: ox_send_cmd(sn,SM_setMathcap);
686: }
687: /* return the server id */
1.2 noro 688: STOZ(ind,*rp);
1.1 noro 689: }
690:
691: #if defined(__CYGWIN32__)
692: static void bslash2slash(char *buf)
693: {
694: char *p;
695:
696: for ( p = buf; *p; p++ )
697: if ( *p == '\\' )
698: *p = '/';
699: }
700:
701: static int get_start_path(char *buf)
702: {
703: static char start_path[BUFSIZ];
704: static int start_initialized = 0;
705: char name[BUFSIZ];
706:
707: if ( start_initialized ) {
708: strcpy(buf,start_path);
709: return 1;
710: }
711:
712: /* Windows98 */
713: strcpy(buf,"c:\\windows\\command\\start.exe");
714: cygwin_conv_to_full_posix_path(buf,name);
715: if ( !access(name,X_OK) ) {
716: bslash2slash(buf);
717: strcpy(start_path,buf);
718: start_initialized = 1;
719: return 1;
720: }
721:
722: /* Windows2000 */
723: strcpy(buf,"c:\\winnt\\system32\\start.exe");
724: cygwin_conv_to_full_posix_path(buf,name);
725: if ( !access(name,X_OK) ) {
726: bslash2slash(buf);
727: strcpy(start_path,buf);
728: start_initialized = 1;
729: return 1;
730: }
731:
732: strcpy(buf,"c:\\winnt\\system32\\cmd.exe");
733: cygwin_conv_to_full_posix_path(buf,name);
734: if ( !access(name,X_OK) ) {
735: bslash2slash(buf);
736: sprintf(start_path,"%s /c start",buf);
737: strcpy(buf,start_path);
738: start_initialized = 1;
739: return 1;
740: }
741:
742: strcpy(buf,"c:\\windows\\system32\\cmd.exe");
743: cygwin_conv_to_full_posix_path(buf,name);
744: if ( !access(name,X_OK) ) {
745: bslash2slash(buf);
746: sprintf(start_path,"%s /c start",buf);
747: strcpy(buf,start_path);
748: start_initialized = 1;
749: return 1;
750: }
751:
752: return 0;
753: }
754:
755: static void get_launcher_path(char *buf)
756: {
757: static char rootname[BUFSIZ];
758: static char launcher_path[BUFSIZ];
759: static int launcher_initialized = 0;
760: char name[BUFSIZ];
761:
762: if ( launcher_initialized ) {
763: strcpy(buf,launcher_path);
764: return;
765: }
766:
767: get_rootdir(rootname,sizeof(rootname));
768: sprintf(name,"%s/ox_launch.exe",rootname);
769: cygwin_conv_to_full_win32_path(name,launcher_path);
770: bslash2slash(launcher_path);
771: launcher_initialized = 1;
772: strcpy(buf,launcher_path);
773: }
774: #endif
775:
776: void spawn_server(char *host,char *launcher,char *server,
777: int use_unix,int use_ssh,int use_x,int conn_to_serv,
778: char *control_port_str,char *server_port_str)
779: {
780: char localhost[BUFSIZ];
781: char *dname,*conn_str,*rsh,*dname0,*asirhost;
782: char AsirExe[BUFSIZ];
783: STRING rootdir;
784: char prog[BUFSIZ];
785: char *av[BUFSIZ];
786: #if !defined(VISUAL) && !defined(__MINGW32__)
787: char cmd[BUFSIZ];
788: #endif
789: #if defined(__CYGWIN__)
790: char win_start[BUFSIZ],win_launcher[BUFSIZ];
791: #endif
792: void Pget_rootdir();
793:
794: dname0 = (char *)getenv("DISPLAY");
795: if ( !dname0 )
796: dname0 = "0";
797: dname = use_x ? dname0 : 0;
798: conn_str = conn_to_serv ? "1" : "0";
799: rsh = getenv("ASIR_RSH");
800: if ( !rsh )
801: rsh = use_ssh ? "ssh" : RSH;
802: if ( !use_unix && strstr(rsh,"ssh") ) {
803: /*
804: * if "ssh" is used to invoke a remote server,
805: * we should not specify "-display".
806: */
807: use_ssh = 1;
808: }
809: asirhost = (char *)getenv("ASIRHOSTNAME");
810: if ( asirhost )
811: strcpy(localhost,asirhost);
812: else
813: gethostname(localhost,BUFSIZ);
814: #if defined(VISUAL) || defined(__MINGW32__)
815: if ( !use_unix )
816: error("spawn_server : not implemented on Windows");
817: Pget_rootdir(&rootdir);
818: sprintf(AsirExe,"%s\\bin\\engine.exe",BDY(rootdir));
819: strcpy(prog,server);
820: server = strrchr(prog,'/')+1;
821: av[0] = "ox_launch";
822: av[1] = "127.0.0.1";
823: av[2] = conn_str;
824: av[3] = control_port_str;
825: av[4] = server_port_str;
826: av[5] = server;
827: av[6] = use_x ? "1" : "0";
828: av[7] = 0;
829:
830: _spawnv(_P_NOWAIT,AsirExe,av);
831: // _spawnv(_P_NOWAIT,"d:\\home\\noro\\engine2000\\debug\\engine.exe",av);
832: // printf("ox_launch 127.0.0.1 %s %s %s %s 0\n",conn_str,control_port_str,server_port_str,server);
833: #else
834: if ( use_unix || !host ) {
835: #if defined(__CYGWIN32__)
836: get_launcher_path(win_launcher);
837: if ( dname && strchr(dname,':') ) {
838: if ( !fork() ) {
839: setpgid(0,getpid());
840: execlp("xterm","xterm","-name",OX_XTERM,"-T","ox_launch:local","-display",dname,
841: "-geometry","60x10","-xrm","XTerm*locale:false","-e",launcher,use_unix?".":"127.1",conn_str,
842: control_port_str,server_port_str,server,dname,(char *)0);
843: }
844: } else if ( dname && get_start_path(win_start) ) {
845: sprintf(cmd,"%s %s %s %s %s %s %s 1",
846: win_start,win_launcher,use_unix?".":"127.1",conn_str,
847: control_port_str,server_port_str,server);
848: system(cmd);
849: } else {
850: if ( !fork() ) {
851: setpgid(0,getpid());
852: execlp(launcher,launcher,use_unix?".":"127.1",conn_str,
853: control_port_str,server_port_str,server,dname0,"-nolog",(char *)0);
854: }
855: }
856: #else
857: if ( !fork() ) {
858: setpgid(0,getpid());
859: if ( dname )
860: execlp("xterm","xterm","-name",OX_XTERM,"-T","ox_launch:local","-display",dname,
861: "-geometry","60x10","-xrm","XTerm*locale:false","-e",launcher,use_unix?".":"127.1",conn_str,
862: control_port_str,server_port_str,server,dname,(char *)0);
863: else
864: execlp(launcher,launcher,use_unix?".":"127.1",conn_str,
865: control_port_str,server_port_str,server,dname0,"-nolog",(char *)0);
866: }
867: #endif
868: } else if ( conn_to_serv == 2 ) {
869: /* special support for java */
870: if ( dname )
871: sprintf(cmd,
872: "%s -n %s \"(cd %s; xterm -name %s %s -geometry 60x10 -e java %s -host %s -control %s -data %s)>&/dev/null&\">/dev/null",
873: rsh,host,launcher,OX_XTERM,dname,server,localhost,control_port_str,server_port_str);
874: else
875: sprintf(cmd,
876: "%s -n %s \"(cd %s; java %s -host %s -control %s -data %s)>&/dev/null&\">/dev/null",
877: rsh,host,launcher,server,localhost,
878: control_port_str,server_port_str,server);
879: fprintf(stderr,"%s\n",cmd);
880: sleep(20);
881: /* system(cmd); */
882: } else {
883: if ( dname )
884: if ( use_ssh )
885: sprintf(cmd,
886: "%s -f -n %s \"xterm -name %s -title ox_launch:%s -geometry 60x10 -xrm 'XTerm*locale:false' -e %s %s %s %s %s %s %s >&/dev/null\">/dev/null",
887: rsh,host,OX_XTERM,host,launcher,localhost,conn_str,
888: control_port_str,server_port_str,server,"1");
889: else
890: sprintf(cmd,
891: "%s -n %s \"xterm -name %s -title ox_launch:%s -display %s -geometry 60x10 -xrm 'XTerm*locale:false' -e %s %s %s %s %s %s %s >&/dev/null&\">/dev/null",
892: rsh,host,OX_XTERM,host,dname,launcher,localhost,conn_str,
893: control_port_str,server_port_str,server,dname);
894: else
895: if ( use_ssh )
896: sprintf(cmd,
897: "%s -f -n %s \"%s %s %s %s %s %s %s %s>&/dev/null&\">/dev/null",
898: rsh,host,launcher,localhost,conn_str,
899: control_port_str,server_port_str,server,"1","-nolog");
900: else
901: sprintf(cmd,
902: "%s -n %s \"%s %s %s %s %s %s %s %s>&/dev/null&\">/dev/null",
903: rsh,host,launcher,localhost,conn_str,
904: control_port_str,server_port_str,server,dname0,"-nolog");
905: system(cmd);
906: }
907: #endif /* VISUAL */
908: }
909:
910: void Pox_launch(NODE arg,Obj *rp)
911: {
912: ox_launch_main(1,arg,rp);
913: }
914:
915: void Pox_launch_nox(NODE arg,Obj *rp)
916: {
917: ox_launch_main(0,arg,rp);
918: }
919:
920: /*
921: ox_launch() : invoke local ox_asir
922: ox_launch(0,ox_xxx) : invoke local ox_xxx with asir_libdir/ox_launch
923: ox_launch(remote,lib,ox_xxx) : invoke remote ox_xxx with lib/ox_launch
924: */
925:
926: void ox_launch_main(int with_x,NODE arg,Obj *p)
927: {
928: char *str;
929: char *hostname,*servername;
930: char *control;
931: int use_unix;
932: Z ret;
933: extern char *asir_libdir;
934:
935: if ( arg && ARG0(arg) && argc(arg) != 3 )
936: error("ox_launch : argument mismatch");
937: control = (char *)MALLOC(BUFSIZ);
938: if ( !arg || ( !ARG0(arg) && argc(arg) == 1 ) ) {
939: sprintf(control,"%s/ox_launch",asir_libdir);
940: use_unix = IS_CYGWIN ? 0 : 1;
941: servername = (char *)MALLOC(BUFSIZ);
942: sprintf(servername,"%s/ox_asir",asir_libdir);
943: } else if ( !ARG0(arg) && argc(arg) == 2 ) {
944: sprintf(control,"%s/ox_launch",asir_libdir);
945: use_unix = IS_CYGWIN ? 0 : 1;
946: str = BDY((STRING)ARG1(arg));
947: if ( str[0] == '/' )
948: servername = str;
949: else {
950: servername = (char *)MALLOC(BUFSIZ);
951: sprintf(servername,"%s/%s",asir_libdir,str);
952: }
953: } else {
954: sprintf(control,"%s/ox_launch",BDY((STRING)ARG1(arg)));
955: if ( !ARG0(arg) )
956: use_unix = IS_CYGWIN ? 0 : 1;
957: else
958: use_unix = 0;
959: str = BDY((STRING)ARG2(arg));
960: if ( str[0] == '/' )
961: servername = str;
962: else {
963: servername = (char *)MALLOC(BUFSIZ);
964: sprintf(servername,"%s/%s",BDY((STRING)ARG1(arg)),str);
965: }
966: }
967: if ( arg && ARG0(arg) )
968: hostname = BDY((STRING)ARG0(arg));
969: else
970: hostname = 0;
971: ox_launch_generic(hostname,control,servername,use_unix,0,with_x,0,&ret);
972: *p = (Obj)ret;
973: }
974:
975: void extend_mctab(int bound)
976: {
977: int i,n;
978: struct m_c *t;
979: if ( !m_c_tab ) {
980: n = (bound/INIT_TAB_SIZ + 1)*INIT_TAB_SIZ;
981: t = (struct m_c *)MALLOC_ATOMIC(n*sizeof(struct m_c));
982: for ( i = m_c_s; i < n; i++ ) {
983: t[i].af_unix = 0;
984: t[i].m = t[i].c = -1;
985: }
986: m_c_s = n; m_c_tab = t;
987: }else if (bound >= m_c_s) {
988: n = (bound/INIT_TAB_SIZ + 1)*INIT_TAB_SIZ;
989: t = (struct m_c *)MALLOC_ATOMIC(n*sizeof(struct m_c));
990: bzero((void *)t,n*sizeof(struct m_c));
991: bcopy((void *)m_c_tab,(void *)t,m_c_s*sizeof(struct m_c));
992: for ( i = m_c_s; i < n; i++ ) {
993: t[i].af_unix = 0;
994: t[i].m = t[i].c = -1;
995: }
996: m_c_s = n; m_c_tab = t;
997: }else {
998: return;
999: }
1000: }
1001:
1002: int available_mcindex(int ind)
1003: {
1004: if (ind < 0) return 1;
1005: extend_mctab(ind);
1006: return m_c_tab[ind].m<0 && m_c_tab[ind].c<0;
1007: }
1008:
1009: int register_server(int af_unix,int m,int c,int ind)
1010: {
1011: int s,i;
1012: struct m_c *t;
1013: if ( c < 0 )
1014: return -1;
1015: extend_mctab( (ind<0)? 0: ind );
1016: if(ind >= 0) {
1017: if (m_c_tab[ind].m<0 && m_c_tab[ind].c<0) {
1018: m_c_tab[ind].m = m; m_c_tab[ind].c = c;
1019: m_c_tab[ind].af_unix = af_unix;
1020: if (ind>=m_c_i) m_c_i = ind+1;
1021: return ind;
1022: }
1023: return -1;
1024: }
1025: #if !defined(MPI)
1026: for ( i = 0; i < m_c_i; i++ )
1027: if ( (m_c_tab[i].m<0) && (m_c_tab[i].c<0) )
1028: break;
1029: if ( i < m_c_i ) {
1030: m_c_tab[i].m = m; m_c_tab[i].c = c;
1031: m_c_tab[i].af_unix = af_unix;
1032: return i;
1033: }
1034: #endif
1035: if ( m_c_i == m_c_s ) {
1036: s = (m_c_s+INIT_TAB_SIZ)*sizeof(struct m_c);
1037: t = (struct m_c *)MALLOC_ATOMIC(s);
1038: bcopy((void *)m_c_tab,(void *)t,m_c_s*sizeof(struct m_c));
1039: for ( i = 0; i < INIT_TAB_SIZ; i++ ) {
1040: t[m_c_s+i].af_unix = 0;
1041: t[m_c_s+i].m = m_c_tab[m_c_s+i].c = -1;
1042: }
1043: m_c_s += INIT_TAB_SIZ; m_c_tab = t;
1044: }
1045: m_c_tab[m_c_i].m = m; m_c_tab[m_c_i].c = c;
1046: m_c_tab[m_c_i].af_unix = af_unix;
1047: return m_c_i++;
1048: }
1049:
1050: /* iofp index => m_c_tab index */
1051:
1052: int get_mcindex(int i)
1053: {
1054: int j;
1055:
1056: for ( j = 0; j < m_c_i; j++ )
1057: if ( m_c_tab[j].c == i )
1058: return j;
1059: return -1;
1060: }
1061:
1062: /* arg = [ind0,ind1,...]; indk = index to m_c_tab */
1063:
1064: void Pox_select(NODE arg,LIST *rp)
1065: {
1066: int fd,n,i,index,mcind,s,maxfd,minfd;
1067: fd_set r,w,e;
1068: NODE list,t,t1,t0;
1069: Z q;
1070: double max;
1071: struct timeval interval;
1072: struct timeval *tvp;
1073:
1074: list = BDY((LIST)ARG0(arg)); arg = NEXT(arg);
1075: if ( arg ) {
1076: max = ToReal((Num)BDY(arg));
1077: interval.tv_sec = (int)max;
1078: interval.tv_usec = (int)((max-(int)max)*1000000);
1079: tvp = &interval;
1080: } else
1081: tvp = 0;
1082:
1083: FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
1084: maxfd = minfd = -1;
1085: for ( t = list, t0 = 0; t; t = NEXT(t) ) {
1.2 noro 1086: index = ZTOS((Q)BDY(t));
1.1 noro 1087: valid_mctab_index(index);
1088: s = m_c_tab[index].c;
1089: if ( ox_data_is_available(s) ) {
1090: MKNODE(t1,(Q)BDY(t),t0); t0 = t1;
1091: } else {
1092: fd = get_fd(s); FD_SET((unsigned int)fd,&r);
1093: maxfd = maxfd<0 ? fd : MAX(fd,maxfd);
1094: minfd = minfd<0 ? fd : MIN(fd,minfd);
1095: }
1096: }
1097: if ( t0 ) {
1098: MKLIST(*rp,t0); return;
1099: }
1100:
1101: n = select(FD_SETSIZE,&r,&w,&e,tvp);
1102: #if defined(VISUAL) || defined(__MINGW32__)
1103: for ( i = minfd, t = 0; n && i <= maxfd; i++ )
1104: #else
1105: for ( i = 0, t = 0; n && i < FD_SETSIZE; i++ )
1106: #endif
1107: if ( FD_ISSET(i,&r) ) {
1108: /* index : index to iofp array */
1109: index = get_index(i);
1110: /* mcind : index to m_c_tab array */
1111: mcind = get_mcindex(index);
1.2 noro 1112: n--; STOZ(mcind,q); MKNODE(t1,q,t); t = t1;
1.1 noro 1113: }
1114: MKLIST(*rp,t);
1115: }
1116:
1117: void Pox_flush(NODE arg,Z *rp)
1118: {
1.2 noro 1119: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1120:
1121: valid_mctab_index(index);
1122: ox_flush_stream_force(m_c_tab[index].c);
1123: *rp = ONE;
1124: }
1125:
1126: void Pox_send_raw_cmo(NODE arg,Obj *rp)
1127: {
1128: int s;
1.2 noro 1129: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1130:
1131: valid_mctab_index(index);
1132: s = m_c_tab[index].c;
1133: ox_write_cmo(s,(Obj)ARG1(arg));
1134: /* flush always */
1135: ox_flush_stream(s);
1136: *rp = 0;
1137: }
1138:
1139: void Pox_recv_raw_cmo(NODE arg,Obj *rp)
1140: {
1141: int s;
1.2 noro 1142: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1143:
1144: valid_mctab_index(index);
1145: s = m_c_tab[index].c;
1146: ox_read_cmo(s,rp);
1147: }
1148:
1149: void Pox_send_102(NODE arg,Obj *rp)
1150: {
1.2 noro 1151: int rank = ZTOS((Q)ARG0(arg));
1.1 noro 1152:
1153: ox_send_data_102(rank,(Obj)ARG1(arg));
1154: *rp = 0;
1155: }
1156:
1157: void Pox_recv_102(NODE arg,Obj *rp)
1158: {
1159: int id;
1.2 noro 1160: int rank = ZTOS((Q)ARG0(arg));
1.1 noro 1161:
1162: ox_recv_102(rank,&id,rp);
1163: }
1164:
1165: void Pox_bcast_102(NODE arg,Obj *rp)
1166: {
1.2 noro 1167: int rank = ZTOS((Q)ARG0(arg));
1.1 noro 1168: Obj data;
1169:
1170: if ( argc(arg) > 1 )
1171: asir_push_one((Obj)ARG1(arg));
1172: ox_bcast_102(rank);
1173: *rp = (Obj)asir_pop_one();
1174: }
1175:
1176: void Pox_reduce_102(NODE arg,Obj *rp)
1177: {
1.2 noro 1178: int root = ZTOS((Q)ARG0(arg));
1.1 noro 1179: STRING op;
1180: char *opname;
1181: void (*func)();
1182:
1183: op = (STRING)ARG1(arg);
1184: asir_assert(op,O_STR,"ox_reduce_102");
1185: opname = BDY(op);
1186: if ( !strcmp(opname,"+") )
1187: func = arf_add;
1188: else if ( !strcmp(opname,"*") )
1189: func = arf_mul;
1190: else {
1191: error("ox_reduce_102 : operation not supported");
1192: }
1193: if ( argc(arg) > 2 )
1194: asir_push_one((Obj)ARG2(arg));
1195: ox_reduce_102(root,func);
1196: *rp = (Obj)asir_pop_one();
1197: }
1198:
1199: void Pox_push_local(NODE arg,Obj *rp)
1200: {
1201: int s;
1202: struct oLIST dummy;
1203: VL vl;
1204: int index;
1205:
1206: if ( !arg )
1207: error("ox_push_local : too few arguments.");
1.2 noro 1208: index = ZTOS((Q)ARG0(arg));
1.1 noro 1209: valid_mctab_index(index);
1210: s = m_c_tab[index].c; arg = NEXT(arg);
1211:
1212: dummy.id = O_LIST; dummy.body = arg;
1213: get_vars_recursive((Obj)&dummy,&vl);
1214:
1215: ox_send_local_ring(s,vl);
1216: for ( ; arg; arg = NEXT(arg) )
1217: ox_send_local_data(s,BDY(arg));
1218: *rp = 0;
1219: }
1220:
1221: void Pox_push_cmo(NODE arg,Obj *rp)
1222: {
1223: int s;
1224: int index;
1225:
1226: if ( !arg )
1227: error("ox_push_cmo : too few arguments.");
1.2 noro 1228: index = ZTOS((Q)ARG0(arg));
1.1 noro 1229: valid_mctab_index(index);
1230: s = m_c_tab[index].c; arg = NEXT(arg);
1231: for ( ; arg; arg = NEXT(arg) )
1232: ox_send_data(s,BDY(arg));
1233: *rp = 0;
1234: }
1235:
1236: void Pox_push_vl(NODE arg,Obj *rp)
1237: {
1.2 noro 1238: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1239:
1240: valid_mctab_index(index);
1241: ox_send_local_ring(m_c_tab[index].c,CO);
1242: *rp = 0;
1243: }
1244:
1245: void Pox_pop_local(NODE arg,Obj *rp)
1246: {
1247: int s;
1.2 noro 1248: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1249:
1250: valid_mctab_index(index);
1251: s = m_c_tab[index].c;
1252: ox_send_cmd(s,SM_popSerializedLocalObject);
1253: ox_flush_stream_force(s);
1254: ox_get_result(s,rp);
1255: }
1256:
1257: void Pox_pop_cmo(NODE arg,Obj *rp)
1258: {
1259: int s;
1.2 noro 1260: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1261:
1262: valid_mctab_index(index);
1263: s = m_c_tab[index].c;
1264: ox_send_cmd(s,SM_popCMO);
1265: ox_flush_stream_force(s);
1266: ox_get_result(s,rp);
1267: }
1268:
1269: void Pox_pop0_local(NODE arg,Obj *rp)
1270: {
1.2 noro 1271: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1272:
1273: valid_mctab_index(index);
1274: ox_send_cmd(m_c_tab[index].c,SM_popSerializedLocalObject);
1275: *rp = 0;
1276: }
1277:
1278: void Pox_pop0_cmo(NODE arg,Obj *rp)
1279: {
1.2 noro 1280: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1281:
1282: valid_mctab_index(index);
1283: ox_send_cmd(m_c_tab[index].c,SM_popCMO);
1284: *rp = 0;
1285: }
1286:
1287: void Pox_pop0_string(NODE arg,STRING *rp)
1288: {
1.2 noro 1289: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1290:
1291: valid_mctab_index(index);
1292: ox_send_cmd(m_c_tab[index].c,SM_popString);
1293: *rp = 0;
1294: }
1295:
1296: void Pox_pop_string(NODE arg,Obj *rp)
1297: {
1298: int s;
1.2 noro 1299: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1300:
1301: valid_mctab_index(index);
1302: s = m_c_tab[index].c;
1303: ox_send_cmd(s,SM_popString);
1304: ox_flush_stream_force(s);
1305: ox_get_result(s,rp);
1306: }
1307:
1308: void Pox_get(NODE arg,Obj *rp)
1309: {
1310: int index;
1311: int s;
1312:
1313: if ( !arg ) {
1314: /* client->server */
1315: ox_get_result(0,rp);
1316: } else {
1317: /* server->client */
1.2 noro 1318: index = ZTOS((Q)ARG0(arg));
1.1 noro 1319: valid_mctab_index(index);
1320: s = m_c_tab[index].c;
1321: ox_flush_stream_force(s);
1322: ox_get_result(s,rp);
1323: }
1324: }
1325:
1326: void Pox_pops(NODE arg,Obj *rp)
1327: {
1328: int s;
1329: USINT n;
1.2 noro 1330: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1331:
1332: valid_mctab_index(index);
1333: s = m_c_tab[index].c;
1334: if ( NEXT(arg) )
1.2 noro 1335: MKUSINT(n,ZTOS((Q)ARG1(arg)));
1.1 noro 1336: else
1337: MKUSINT(n,1);
1338: ox_send_data(s,n);
1339: ox_send_cmd(s,SM_pops);
1340: *rp = 0;
1341: }
1342:
1343: void Pox_execute_function(NODE arg,Obj *rp)
1344: {
1345: int s;
1346: USINT ui;
1.2 noro 1347: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1348:
1349: valid_mctab_index(index);
1350: s = m_c_tab[index].c;
1.2 noro 1351: MKUSINT(ui,ZTOS((Q)ARG2(arg)));
1.1 noro 1352: ox_send_data(s,ui);
1353: ox_send_data(s,ARG1(arg));
1354: ox_send_cmd(s,SM_executeFunction);
1355: *rp = 0;
1356: }
1357:
1358: void Pox_setname(NODE arg,Obj *rp)
1359: {
1360: int s;
1.2 noro 1361: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1362:
1363: valid_mctab_index(index);
1364: s = m_c_tab[index].c;
1365: ox_send_data(s,ARG1(arg));
1366: ox_send_cmd(s,SM_setName);
1367: *rp = 0;
1368: }
1369:
1370: void Pox_evalname(NODE arg,Obj *rp)
1371: {
1372: int s;
1.2 noro 1373: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1374:
1375: valid_mctab_index(index);
1376: s = m_c_tab[index].c;
1377: ox_send_data(s,ARG1(arg));
1378: ox_send_cmd(s,SM_evalName);
1379: *rp = 0;
1380: }
1381:
1382: void Pox_execute_string(NODE arg,Obj *rp)
1383: {
1384: int s;
1.2 noro 1385: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1386:
1387: asir_assert(ARG1(arg),O_STR,"ox_execute_string");
1388: valid_mctab_index(index);
1389: s = m_c_tab[index].c;
1390: ox_send_data(s,ARG1(arg));
1391: ox_send_cmd(s,SM_executeStringByLocalParser);
1392: *rp = 0;
1393: }
1394:
1395: /* arg=[sid,fname,arg0,arg1,...,arg{n-1}] */
1396:
1397: void Pox_rpc(NODE arg,Obj *rp)
1398: {
1399: int s,i,n;
1400: STRING f;
1401: USINT ui;
1402: pointer *w;
1403: NODE t;
1.2 noro 1404: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1405:
1406: valid_mctab_index(index);
1407: s = m_c_tab[index].c; arg = NEXT(arg);
1408: f = (STRING)BDY(arg); arg = NEXT(arg);
1409: ox_send_local_ring(s,CO);
1410: for ( n = 0, t = arg; t; t = NEXT(t), n++ );
1411: w = (pointer *)ALLOCA(n*sizeof(pointer));
1412: for ( i = 0, t = arg; i < n; t = NEXT(t), i++ )
1413: w[i] = BDY(t);
1414: for ( i = n-1; i >= 0; i-- )
1415: ox_send_local_data(s,w[i]);
1416: MKUSINT(ui,n);
1417: ox_send_data(s,ui);
1418: ox_send_data(s,f);
1419: ox_send_cmd(s,SM_executeFunction);
1420: *rp = 0;
1421: }
1422:
1423: void Pox_cmo_rpc(NODE arg,Obj *rp)
1424: {
1425: int s,i,n;
1426: STRING f;
1427: USINT ui;
1428: NODE t;
1429: Obj dmy;
1430: pointer *w;
1.2 noro 1431: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1432: int find;
1433: Obj sync;
1434:
1435: find = get_opt("sync",&sync);
1436: valid_mctab_index(index);
1437: s = m_c_tab[index].c; arg = NEXT(arg);
1438: f = (STRING)BDY(arg); arg = NEXT(arg);
1439: for ( n = 0, t = arg; t; t = NEXT(t), n++ );
1440: w = (pointer *)ALLOCA(n*sizeof(pointer));
1441: for ( i = 0, t = arg; i < n; t = NEXT(t), i++ )
1442: w[i] = BDY(t);
1443: for ( i = n-1; i >= 0; i-- )
1444: ox_send_data(s,w[i]);
1445: MKUSINT(ui,n);
1446: ox_send_data(s,ui);
1447: ox_send_data(s,f);
1448: if ( find && sync ) {
1449: ox_send_cmd(s,SM_executeFunctionSync);
1450: ox_get_result(s,&dmy);
1451: } else
1452: ox_send_cmd(s,SM_executeFunction);
1453: *rp = 0;
1454: }
1455:
1456: int No_ox_reset;
1457: extern Z ox_pari_stream;
1458: extern int ox_pari_stream_initialized;
1459:
1460: void Pox_reset(NODE arg,Z *rp)
1461: {
1462: USINT t;
1463: int id,c,m;
1464: Obj obj;
1465: NODE nd;
1466: Z q;
1.2 noro 1467: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1468:
1469: valid_mctab_index(index);
1470: m = m_c_tab[index].m;
1471: c = m_c_tab[index].c;
1472: if ( m >= 0 ) {
1473: if ( no_ox_reset(c) == 1 ) {
1.2 noro 1474: STOZ(index,q);
1.1 noro 1475: nd = mknode(1,q);
1476: switch ( No_ox_reset ) {
1477: case 1:
1478: fprintf(stderr,"The server does not implenent OX reset protocol.\n");
1479: fprintf(stderr,"The server is terminated.\n");
1480: Pox_shutdown(nd,rp);
1.2 noro 1481: if ( index == ZTOS(ox_pari_stream) ) ox_pari_stream_initialized = 0;
1.1 noro 1482: break;
1483: case 2:
1484: Pox_shutdown(nd,rp);
1.2 noro 1485: if ( index == ZTOS(ox_pari_stream) ) ox_pari_stream_initialized = 0;
1.1 noro 1486: break;
1487: default:
1488: error("The server does not implement OX reset protocol.");
1489: *rp = ONE;
1490: break;
1491: }
1492: return;
1493: }
1494:
1495: if ( argc(arg) == 1 ) {
1496: ox_send_cmd(m,SM_control_reset_connection);
1497: ox_flush_stream_force(m);
1498: #if 0
1499: /* XXX obsolete */
1500: ox_recv(m,&id,&obj); t = (USINT)obj;
1501: #endif
1502: }
1503: *rp = ONE;
1504: #if defined(VISUAL) || defined(__MINGW32__)
1505: Sleep(100);
1506: ox_send_cmd(c,SM_nop);
1507: ox_flush_stream_force(c);
1508: #endif
1509: while ( 1 ) {
1510: ox_recv(c,&id,&obj);
1511: if ( id == OX_SYNC_BALL )
1512: break;
1513: }
1514: ox_send_sync(c);
1515: } else
1516: *rp = 0;
1517: }
1518:
1519: void Pox_intr(NODE arg,Z *rp)
1520: {
1521: int m;
1.2 noro 1522: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1523:
1524: valid_mctab_index(index);
1525: m = m_c_tab[index].m;
1526: if ( m >= 0 ) {
1527: if ( argc(arg) == 1 ) {
1528: ox_send_cmd(m,SM_control_intr);
1529: ox_flush_stream_force(m);
1530: }
1531: *rp = ONE;
1532: } else
1533: *rp = 0;
1534: }
1535:
1536: void Pox_sync(NODE arg,Z *rp)
1537: {
1538: int c;
1.2 noro 1539: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1540:
1541: valid_mctab_index(index);
1542: c = m_c_tab[index].c;
1543: ox_send_sync(c);
1544: *rp = 0;
1545: }
1546:
1547: void Pox_shutdown(NODE arg,Z *rp)
1548: {
1549: int s;
1.2 noro 1550: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1551: #if !defined(VISUAL) && !defined(__MINGW32__)
1552: int status;
1553: #endif
1554:
1555: valid_mctab_index(index);
1556: s = m_c_tab[index].m;
1557: ox_send_cmd(s,SM_shutdown);
1558: free_iofp(s);
1559: s = m_c_tab[index].c;
1560: free_iofp(s);
1561: #if !defined(MPI) && !defined(VISUAL) && !defined(__MINGW32__)
1562: if ( m_c_tab[index].af_unix )
1563: wait(&status);
1564: #endif
1565: m_c_tab[index].m = -1; m_c_tab[index].c = -1;
1566: m_c_tab[index].af_unix = 0;
1567: *rp = 0;
1568: }
1569:
1570: void Pox_push_cmd(NODE arg,Z *rp)
1571: {
1572: int ui;
1.2 noro 1573: int index = ZTOS((Q)ARG0(arg));
1.1 noro 1574:
1575: valid_mctab_index(index);
1.2 noro 1576: ui = ZTOS((Q)ARG1(arg));
1.1 noro 1577: ox_send_cmd(m_c_tab[index].c,ui);
1578: *rp = 0;
1579: }
1580:
1581: void shutdown_all() {
1582: int s;
1583: int i,index;
1584: #if !defined(VISUAL) && !defined(__MINGW32__)
1585: int status;
1586: #endif
1587:
1588: for ( i = I_am_server?1:0; i < m_c_i; i++ ) {
1589: index = i;
1590: check_valid_mctab_index(index);
1591: if ( index < 0 )
1592: continue;
1593: s = m_c_tab[index].m;
1594: ox_send_cmd(s,SM_shutdown);
1595: #if defined(VISUAL) || defined(__MINGW32__)
1596: Sleep(1000);
1597: #endif
1598: free_iofp(s);
1599: s = m_c_tab[index].c;
1600: free_iofp(s);
1601: #if !defined(MPI) && !defined(VISUAL) && !defined(__MINGW32__)
1602: if ( m_c_tab[index].af_unix )
1603: wait(&status);
1604: #endif
1605: m_c_tab[index].m = 0; m_c_tab[index].c = 0;
1606: m_c_tab[index].af_unix = 0;
1607: }
1608: }
1609:
1610: char *ox_get_servername(int);
1611:
1612: int is_ox_plot(int index)
1613: {
1614: char *name;
1615:
1616: check_valid_mctab_index(index);
1617: if ( index < 0 )
1618: return 0;
1619: /* m : client, c : server ??? */
1620: name = ox_get_servername(m_c_tab[index].c);
1621: return strcmp(name,"ox_plot") ? 0 : 1;
1622: }
1623:
1624: int debug_plot;
1625:
1626: int validate_ox_plot_stream(int index)
1627: {
1628: int i;
1629: NODE arg;
1630: STRING name;
1631: Obj r;
1632:
1633: if ( is_ox_plot(index) )
1634: return index;
1635: for ( i = 0; i < m_c_i; i++ )
1636: if ( is_ox_plot(i) )
1637: return i;
1638:
1639: /* create an ox_plot server */
1640: MKSTR(name,"ox_plot");
1641: arg = mknode(2,NULL,name);
1642: if ( debug_plot ) Pox_launch(arg,&r);
1643: else Pox_launch_nox(arg,&r);
1.2 noro 1644: i = ZTOS((Q)r);
1.1 noro 1645: #if defined(VISUAL) || defined(__MINGW32__)
1646: Sleep(100);
1647: ox_send_cmd(m_c_tab[i].c,SM_nop);
1648: ox_flush_stream_force(m_c_tab[i].c);
1649: #endif
1650: return i;
1651: }
1652:
1653: int get_ox_server_id(int index)
1654: {
1655: valid_mctab_index(index);
1656: return m_c_tab[index].c;
1657: }
1658:
1659: int register_102(int s1,int rank,int is_master)
1660: {
1661: unsigned char c,rc;
1662:
1663: if ( rank >= MAXIOFP ) return -1;
1664: iofp_102[rank].s = s1;
1665: #if defined(VISUAL) || defined(__MINGW32__)
1666: iofp_102[rank].in = WSIO_open(s1,"r");
1667: iofp_102[rank].out = WSIO_open(s1,"w");
1668: #else
1669: iofp_102[rank].in = fdopen(s1,"r");
1670: iofp_102[rank].out = fdopen(s1,"w");
1671: #if !defined(__CYGWIN__)
1672: setbuffer(iofp_102[rank].in,iofp_102[rank].inbuf =
1673: (char *)MALLOC_ATOMIC(LBUFSIZ),LBUFSIZ);
1674: setbuffer(iofp_102[rank].out,iofp_102[rank].outbuf =
1675: (char *)MALLOC_ATOMIC(LBUFSIZ),LBUFSIZ);
1676: #endif
1677: #endif
1678: if ( little_endian )
1679: c = 1;
1680: else
1681: c = 0xff;
1682: if ( is_master ) {
1683: /* server : write -> read */
1684: write_char((FILE *)iofp_102[rank].out,&c);
1685: ox_flush_stream_force_102(rank);
1686: read_char((FILE *)iofp_102[rank].in,&rc);
1687: } else {
1688: /* client : read -> write */
1689: read_char((FILE *)iofp_102[rank].in,&rc);
1690: /* special care for a failure of spawing a server */
1691: if ( rc !=0 && rc != 1 && rc != 0xff )
1692: return -1;
1693: write_char((FILE *)iofp_102[rank].out,&c);
1694: ox_flush_stream_force_102(rank);
1695: }
1696: iofp_102[rank].conv = c == rc ? 0 : 1;
1697: iofp_102[rank].socket = 0;
1698: return 0;
1699: }
1700:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>