~ubuntu-branches/ubuntu/saucy/nwchem/saucy

« back to all changes in this revision

Viewing changes to src/tools/ga-4-3/armci/src/sockets.c

  • Committer: Package Import Robot
  • Author(s): Michael Banck, Michael Banck, Daniel Leidert
  • Date: 2012-02-09 20:02:41 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120209200241-jgk03qfsphal4ug2
Tags: 6.1-1
* New upstream release.

[ Michael Banck ]
* debian/patches/02_makefile_flags.patch: Updated.
* debian/patches/02_makefile_flags.patch: Use internal blas and lapack code.
* debian/patches/02_makefile_flags.patch: Define GCC4 for LINUX and LINUX64
  (Closes: #632611 and LP: #791308).
* debian/control (Build-Depends): Added openssh-client.
* debian/rules (USE_SCALAPACK, SCALAPACK): Removed variables (Closes:
  #654658).
* debian/rules (LIBDIR, USE_MPIF4, ARMCI_NETWORK): New variables.
* debian/TODO: New file.
* debian/control (Build-Depends): Removed libblas-dev, liblapack-dev and
  libscalapack-mpi-dev.
* debian/patches/04_show_testsuite_diff_output.patch: New patch, shows the
  diff output for failed tests.
* debian/patches/series: Adjusted.
* debian/testsuite: Optionally run all tests if "all" is passed as option.
* debian/rules: Run debian/testsuite with "all" if DEB_BUILD_OPTIONS
  contains "checkall".

[ Daniel Leidert ]
* debian/control: Used wrap-and-sort. Added Vcs-Svn and Vcs-Browser fields.
  (Priority): Moved to extra according to policy section 2.5.
  (Standards-Version): Bumped to 3.9.2.
  (Description): Fixed a typo.
* debian/watch: Added.
* debian/patches/03_hurd-i386_define_path_max.patch: Added.
  - Define MAX_PATH if not defines to fix FTBFS on hurd.
* debian/patches/series: Adjusted.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: sockets.c,v 1.23.8.1 2007-02-09 17:10:18 andriy Exp $ */
 
2
/**************************************************************************
 
3
 Some parts of this code were derived from the TCGMSG file sockets.c
 
4
 Jarek Nieplocha, last update 10/28/99
 
5
 02/28/00: modified armci_WaitSock to allow some elements of socklist to 
 
6
           be <0 (and ignored). Needed for the threaded version of server.
 
7
 *************************************************************************/
 
8
 
 
9
#include <stdio.h>
 
10
#include <string.h>
 
11
#include <errno.h>
 
12
 
 
13
#ifdef WIN32
 
14
#  include <winsock.h>
 
15
#  define bcopy(s1,s2,n) memcpy(s2,s1,n)
 
16
#  define sleep(x) Sleep(1000*(x))
 
17
#  define CLOSE closesocket
 
18
#else
 
19
#  include <sys/wait.h>
 
20
#  include <sys/time.h>
 
21
#  include <sys/types.h>
 
22
#  include <sys/socket.h>
 
23
/*#  include <sys/uio.h> */ /*moved to sockets.h*/ 
 
24
#  include <netinet/in.h>
 
25
#  include <netinet/tcp.h>
 
26
#  include <netdb.h>
 
27
#  include <unistd.h>
 
28
#  define CLOSE close
 
29
#endif
 
30
 
 
31
#include "armcip.h"
 
32
#include "sockets.h"
 
33
 
 
34
#ifdef AIX
 
35
#  include <standards.h>
 
36
#  include <sys/select.h>
 
37
#  ifdef _AIXVERSION_430
 
38
     typedef socklen_t soclen_t;
 
39
#  else
 
40
     typedef size_t soclen_t;
 
41
#  endif
 
42
#elif defined(XLCLINUX)
 
43
typedef socklen_t soclen_t;
 
44
#else
 
45
typedef int soclen_t;
 
46
#endif
 
47
 
 
48
 
 
49
#ifdef CRAY
 
50
#include <memory.h>
 
51
#endif
 
52
 
 
53
/* portability of socklen_t definition is iffy - we need to avoid it !!
 
54
#if defined(LINUX) && ( defined(_SOCKETBITS_H) || defined(__BITS_SOCKET_H))
 
55
#elif defined(AIX)
 
56
  typedef size_t socklen_t;
 
57
#else
 
58
  typedef int socklen_t;
 
59
#endif
 
60
*/
 
61
 
 
62
#ifndef MAX_STRIDE_LEVEL
 
63
#define MAX_STRIDE_LEVEL 8
 
64
#endif
 
65
 
 
66
extern int armci_me, armci_nproc,armci_nclus;
 
67
int tcp_sendrcv_bufsize=131072;
 
68
#define DEBUG_ 0
 
69
#define DEBUG1 0
 
70
#define CONNECT_TRIALS 4 
 
71
#define MAX_INTR_NO_DATA 8
 
72
 
 
73
int armci_PollSocket(int sock)
 
74
/*
 
75
  Poll the socket for available input.
 
76
 
 
77
  Return 1 if data is available, 0 otherwise.
 
78
*/
 
79
{
 
80
  fd_set ready;
 
81
  struct timeval timelimit;
 
82
  int nready;
 
83
 
 
84
  if (sock < 0)
 
85
    return 0;
 
86
 
 
87
again:
 
88
  FD_ZERO(&ready);
 
89
  FD_SET(sock, &ready);
 
90
  timelimit.tv_sec = 0;
 
91
  timelimit.tv_usec = 0;
 
92
 
 
93
  nready = select(sock+1, &ready, (fd_set *) NULL, (fd_set *) NULL, &timelimit);
 
94
  if (nready < 0) {
 
95
    if (errno == EINTR)
 
96
      goto again;
 
97
    else
 
98
      armci_die("armci_PollSocket: error from select",   sock);
 
99
  }
 
100
 
 
101
  return nready;
 
102
}
 
103
 
 
104
 
 
105
/*\ sleep in select until data appears on one of sockets
 
106
 *  return number of sockets ready and indicate which ones are in ready array
 
107
 *  allows <0 values in socklist array (ignores them)
 
108
\*/
 
109
int armci_WaitSock(int *socklist, int num, int *ready)
 
110
{
 
111
 
 
112
  int sock,maxsock=0;
 
113
  fd_set dset;
 
114
  int nready;
 
115
 
 
116
  if(num<0) armci_die("armci_WaitSock: num <0",num);
 
117
 
 
118
again:
 
119
 
 
120
  FD_ZERO(&dset);
 
121
  maxsock=0;
 
122
  for(sock=0; sock<num; sock++){
 
123
     if(socklist[sock] > maxsock)maxsock = socklist[sock];
 
124
 
 
125
     if(socklist[sock] >0){ /* ignore fd=-1 on the list */
 
126
        FD_SET(socklist[sock], &dset);
 
127
     }
 
128
  }
 
129
 
 
130
 
 
131
  nready = select(maxsock+1, &dset, (fd_set*)NULL, (fd_set*)NULL, NULL);
 
132
 
 
133
    if (nready < 0) {
 
134
    if (errno == EINTR){
 
135
      fprintf(stderr,"%d:interrupted in select\n",armci_me);
 
136
      goto again;
 
137
    } else
 
138
      armci_die("armci_WaitSocket: error from select",   sock);
 
139
  }
 
140
 
 
141
 
 
142
  for(sock=0; sock<num; sock++){
 
143
     ready[sock]=0;
 
144
     if(socklist[sock] < 0) continue;
 
145
     if(FD_ISSET(socklist[sock],&dset)) ready[sock]=1;
 
146
  }
 
147
 
 
148
  return nready;
 
149
}
 
150
 
 
151
/* same as armci_WaitSock with lim nano-seconds timeout */
 
152
int armci_WaitSockLim(int *socklist, int num, int *ready, int lim)
 
153
{
 
154
  struct timeval timelimit;
 
155
  int sock,maxsock=0;
 
156
  fd_set dset;
 
157
  int nready;
 
158
 
 
159
  if(num<0) armci_die("armci_WaitSock: num <0",num);
 
160
 
 
161
again:
 
162
 
 
163
  FD_ZERO(&dset);
 
164
  maxsock=0;
 
165
  for(sock=0; sock<num; sock++){
 
166
     if(socklist[sock] > maxsock)maxsock = socklist[sock];
 
167
 
 
168
     if(socklist[sock] >0){ /* ignore fd=-1 on the list */
 
169
        FD_SET(socklist[sock], &dset);
 
170
     }
 
171
  }
 
172
  timelimit.tv_sec = 0;
 
173
  timelimit.tv_usec = lim;
 
174
 
 
175
 
 
176
  nready = select(maxsock+1, &dset, (fd_set*)NULL, (fd_set*)NULL, &timelimit);
 
177
 
 
178
    if (nready < 0) {
 
179
    if (errno == EINTR){
 
180
      fprintf(stderr,"%d:interrupted in select\n",armci_me);
 
181
      goto again;
 
182
    } else
 
183
      armci_die("armci_WaitSocket: error from select",   sock);
 
184
  }
 
185
 
 
186
 
 
187
  for(sock=0; sock<num; sock++){
 
188
     ready[sock]=0;
 
189
     if(socklist[sock] < 0) continue;
 
190
     if(FD_ISSET(socklist[sock],&dset)) ready[sock]=1;
 
191
  }
 
192
 
 
193
  return nready;
 
194
}
 
195
 
 
196
 
 
197
 
 
198
 
 
199
 
 
200
void armci_TcpNoDelay( int sock)
 
201
/*
 
202
  Turn off waiting for more input to improve buffering 
 
203
  by TCP layer ... improves performance for small messages by
 
204
  a factor of 30 or more. Slightly degrades performance for
 
205
  large messages.
 
206
*/
 
207
{
 
208
  int status, level, value=1;
 
209
#ifdef AIX
 
210
  struct protoent *proto = getprotobyname("tcp");
 
211
#else
 
212
  struct protoent *proto = getprotobyname("TCP");
 
213
#endif
 
214
  void *optval = &value;
 
215
 
 
216
  if (proto == (struct protoent *) NULL)
 
217
    armci_die("armci_TcpNoDelay: getprotobyname on TCP failed!",  -1);
 
218
 
 
219
  level = proto->p_proto;
 
220
 
 
221
  status = setsockopt(sock, level, TCP_NODELAY, optval, sizeof(int));
 
222
 
 
223
  if (status != 0)
 
224
    armci_die("armci_TcpNoDelay: setsockopt failed",  status);
 
225
}
 
226
 
 
227
 
 
228
 
 
229
void armci_ShutdownAll(int socklist[], int num)
 
230
/* 
 
231
   close all sockets discarding any pending data in either direction.
 
232
*/
 
233
{
 
234
   int i;
 
235
 
 
236
   for (i=0; i<num; i++)
 
237
      if (socklist[i] >= 0) {
 
238
         (void) shutdown(socklist[i], 2);
 
239
         (void) CLOSE(socklist[i]);
 
240
         socklist[i]=-1;
 
241
      }
 
242
}
 
243
 
 
244
 
 
245
#if defined(USE_SOCKET_VECTOR_API) 
 
246
 
 
247
int _armci_tcp_writev(int sock, struct iovec *iovptr,int writeiovlength,int currentwritesize,struct iovec *iov){
 
248
    int n=0;
 
249
    while(n!=currentwritesize){
 
250
        int rc;
 
251
        rc=writev(sock,iovptr,writeiovlength);
 
252
        if(rc<0)perror("writev failed");
 
253
        if(DEBUG1&&0)if(rc<currentwritesize){printf("\n%d:_armci_tcp_writev write %d bytes of %d bytes writeiovlen=%d",armci_me,rc,currentwritesize,writeiovlength);fflush(stdout);} 
 
254
        n+=rc;
 
255
        if(n<currentwritesize){
 
256
            int completediovs=0;
 
257
            int templength=0;
 
258
            while(templength!=rc){
 
259
                if(iovptr->iov_len+templength>rc){
 
260
                    iovptr->iov_base=(char *)((*iovptr).iov_base)+(rc-templength);
 
261
                    iovptr->iov_len-=(rc-templength);
 
262
                    templength+=(rc-templength);
 
263
                }
 
264
                else {
 
265
                    templength+=iovptr->iov_len;
 
266
                    iovptr+=1;
 
267
                    completediovs++;
 
268
                }
 
269
            }
 
270
            writeiovlength-=completediovs;
 
271
            if(writeiovlength<=0)writeiovlength=1;
 
272
        } 
 
273
    }
 
274
    return(n);
 
275
}
 
276
 
 
277
int _armci_tcp_readv(int sock, struct iovec *iovptr,int readiovlength,int currentreadsize,struct iovec *iov){
 
278
    int n=0;
 
279
    while(n!=currentreadsize){
 
280
        int rc;
 
281
        rc=readv(sock,iovptr,readiovlength);
 
282
        if(rc<0)perror("readv failed");
 
283
        if(DEBUG1&&0)if(rc<currentreadsize){printf("\n%d:_armci_tcp_readv Read %d bytes of %d bytes readiovlen=%d",armci_me,rc,currentreadsize,readiovlength);fflush(stdout);}
 
284
        n+=rc;
 
285
        if(n<currentreadsize){
 
286
            int completediovs=0;
 
287
            int templength=0;
 
288
            while(templength!=rc){
 
289
                if(iovptr->iov_len+templength>rc){
 
290
                    iovptr->iov_base=(char *)((*iovptr).iov_base)+(rc-templength);
 
291
                    iovptr->iov_len-=(rc-templength);
 
292
                    templength+=(rc-templength);
 
293
                }
 
294
                else {
 
295
                    templength+=iovptr->iov_len;
 
296
                    iovptr+=1;
 
297
                    completediovs++;
 
298
                }
 
299
            }
 
300
            readiovlength-=completediovs;
 
301
            if(readiovlength<=0)readiovlength=1;
 
302
        }
 
303
    }
 
304
    return(n);
 
305
}
 
306
 
 
307
int armci_ReadVFromSocket(int sock,struct iovec *iov, int iovlength, int totalsize)
 
308
{
 
309
    struct iovec *iovptr;
 
310
    int i=0,num_xmit=1,lastiovoriglen=0,lastiovnewlen=0,lastiovindex=-1,n=0;
 
311
    int readiovlength,currentreadsize=totalsize,totalreadsofar=0,byteslefttoread=0;
 
312
    char *lastiovorigbase=NULL;
 
313
    iovptr=iov; 
 
314
    if(totalsize>PACKET_SIZE){
 
315
        while(totalreadsofar!=totalsize){
 
316
            currentreadsize=0;
 
317
            if(lastiovindex>=0)
 
318
                iovptr=iov+lastiovindex;
 
319
            if(lastiovoriglen!=0){
 
320
                iov[lastiovindex].iov_base = (lastiovorigbase+lastiovnewlen); 
 
321
                iov[lastiovindex].iov_len=lastiovoriglen-lastiovnewlen;
 
322
                lastiovoriglen=0;   
 
323
            } 
 
324
            iovlength=0;  
 
325
            
 
326
            if(totalsize-totalreadsofar<PACKET_SIZE)byteslefttoread=totalsize-totalreadsofar;
 
327
            else byteslefttoread=PACKET_SIZE;
 
328
            while(currentreadsize<byteslefttoread){
 
329
                if(iov[i].iov_len+currentreadsize>byteslefttoread){
 
330
                    lastiovoriglen=iov[i].iov_len;lastiovorigbase=(char *)iov[i].iov_base;
 
331
                    lastiovindex=i; 
 
332
                    iov[i].iov_len=byteslefttoread-currentreadsize;
 
333
                    currentreadsize+=iov[i].iov_len; lastiovnewlen=iov[i].iov_len;
 
334
                }
 
335
                else {  
 
336
                    currentreadsize+=iov[i].iov_len;
 
337
                    i++;
 
338
                    lastiovindex=i;
 
339
                    iovlength++;
 
340
                }
 
341
            }
 
342
            if(lastiovoriglen>0)iovlength+=1;
 
343
            totalreadsofar+=currentreadsize;
 
344
            num_xmit++;
 
345
            readiovlength=iovlength;
 
346
            n=_armci_tcp_readv(sock,iovptr,readiovlength,currentreadsize,iov);  
 
347
        if(DEBUG1){printf("\nFinished reading n=%d bytes iov of length %d \n",n,iovlength);fflush(stdout);}
 
348
        }
 
349
    }
 
350
    else {
 
351
        iovptr=iov;
 
352
        readiovlength=iovlength;
 
353
        n=0;
 
354
        n+=_armci_tcp_readv(sock,iovptr,readiovlength,currentreadsize,iov); 
 
355
        if(DEBUG1){printf("\nFits in one packet Finished reading n=%d bytes iov of length %d \n",n,iovlength);fflush(stdout);}
 
356
     }  
 
357
    return(n);
 
358
}
 
359
 
 
360
 
 
361
int armci_WriteVToSocket(int sock,struct iovec *iov, int iovlength, int totalsize){     
 
362
 
 
363
    int lastiovoriglen=0,lastiovnewlen=0,lastiovindex=-1,totalwritesofar=0,byteslefttowrite=0;
 
364
    struct iovec *iovptr; 
 
365
    int i=0,num_xmit=0,n=0;
 
366
    int currentwritesize=totalsize,writeiovlength;
 
367
     char *lastiovorigbase=NULL;
 
368
    iovptr=iov; 
 
369
    if(totalsize>PACKET_SIZE){
 
370
        while(totalwritesofar!=totalsize){      
 
371
            currentwritesize=0; 
 
372
            if(lastiovindex>=0)
 
373
                iovptr=iov+lastiovindex;
 
374
            if(lastiovoriglen!=0){
 
375
                iov[lastiovindex].iov_base = (lastiovorigbase+lastiovnewlen); 
 
376
                iov[lastiovindex].iov_len= lastiovoriglen-lastiovnewlen;
 
377
                lastiovoriglen=0;
 
378
            }
 
379
            iovlength=0;
 
380
          
 
381
            if(totalsize-totalwritesofar<PACKET_SIZE)byteslefttowrite=totalsize-totalwritesofar;
 
382
            else byteslefttowrite=PACKET_SIZE;
 
383
            while(currentwritesize<byteslefttowrite){
 
384
                if(iov[i].iov_len+currentwritesize>byteslefttowrite){
 
385
                    lastiovoriglen=iov[i].iov_len;lastiovorigbase=(char *)iov[i].iov_base;
 
386
                    lastiovindex=i;
 
387
                    iov[i].iov_len=byteslefttowrite-currentwritesize;
 
388
                    currentwritesize+=iov[i].iov_len;lastiovnewlen=iov[i].iov_len;
 
389
                }
 
390
                else {
 
391
                    currentwritesize+=iov[i].iov_len;
 
392
                    i++;
 
393
                    lastiovindex=i;
 
394
                    iovlength++;
 
395
                }
 
396
            }
 
397
            totalwritesofar+=currentwritesize;
 
398
            num_xmit++;
 
399
            if(lastiovoriglen>0)iovlength+=1;
 
400
            writeiovlength=iovlength;     
 
401
            n=_armci_tcp_writev(sock,iovptr,writeiovlength,currentwritesize,iov); 
 
402
            if(DEBUG1){printf("\nFinished writing n=%d iov of length %d \n",n,iovlength);fflush(stdout);}
 
403
            if(n!=currentwritesize)armci_die2("\n problems with writing using writev\n",n,currentwritesize);
 
404
        }
 
405
  
 
406
    }
 
407
    else {
 
408
        iovptr=iov;
 
409
        writeiovlength=iovlength;  
 
410
        n=0;
 
411
        n= _armci_tcp_writev(sock,iovptr,writeiovlength,currentwritesize,iov); 
 
412
        if(n<0)perror("write failed");
 
413
        if(DEBUG1){printf("\nFits in one packet Finished writing n=%d iov of length %d \n",n,iovlength);fflush(stdout);}
 
414
        if(n!=currentwritesize)armci_die2("\n problems with writing using writev\n",n,currentwritesize);
 
415
    } 
 
416
    return(n);
 
417
}
 
418
 
 
419
#endif /*for use_socket_vec_api*/  
 
420
 
 
421
int armci_ReadFromSocket(int sock, void* buffer, int lenbuf)
 
422
/*
 
423
   Read from the socket until we get all we want.
 
424
*/
 
425
{
 
426
 
 
427
   int nread, status, nintr=0;
 
428
   char *buf = (char*)buffer;
 
429
   status = lenbuf;
 
430
   while (lenbuf > 0) {
 
431
again:
 
432
     
 
433
     nread = recv(sock, buf, lenbuf, 0);
 
434
     /* on linux 0 can be returned if socket is closed  by sender */ 
 
435
     if(nread < 0 || ((nread ==  0) && errno ) ){
 
436
       if (errno == EINTR){
 
437
 
 
438
         if(DEBUG_){
 
439
           fprintf(stderr,"%d:interrupted in recv\n",armci_me);
 
440
         }
 
441
 
 
442
         /* retry a few times if nread==0 */
 
443
         if(nread==0) nintr++; 
 
444
         else nintr=0;
 
445
         if(nintr>MAX_INTR_NO_DATA) return -1; /* the socket must be closed */
 
446
 
 
447
         goto again;
 
448
 
 
449
       }else {
 
450
         if(DEBUG_){
 
451
           (void) fprintf(stderr,"sock=%d, pid=%d, nread=%d, len=%d\n",
 
452
                               sock, armci_me, nread, lenbuf);
 
453
           if(errno)perror("armci_ReadFromSocket: recv failed");
 
454
         }
 
455
         status = -1;
 
456
         break;
 
457
       }
 
458
     }
 
459
     buf += nread;
 
460
     lenbuf -= nread;
 
461
   }
 
462
    
 
463
   return status;
 
464
}
 
465
 
 
466
 
 
467
int armci_WriteToSocket (int sock, void* buffer, int lenbuf)
 
468
/*
 
469
  Write to the socket in packets of PACKET_SIZE bytes
 
470
*/
 
471
{
 
472
  int status = lenbuf;
 
473
  int nsent, len;
 
474
  char *buf = (char*)buffer;
 
475
 
 
476
  if(DEBUG_){
 
477
    printf("%d armci_WriteToSocket sock=%d lenbuf=%d\n",armci_me,sock,lenbuf);
 
478
    fflush(stdout);
 
479
  }
 
480
 
 
481
  while (lenbuf > 0) {
 
482
again:
 
483
 
 
484
    len = (lenbuf > PACKET_SIZE) ? PACKET_SIZE : lenbuf;
 
485
    nsent = send(sock, buf, len, 0);
 
486
   
 
487
    if (nsent < 0) { /* This is bad news */
 
488
      if(errno ==EINTR){
 
489
         if(DEBUG_){
 
490
           fprintf(stderr,"%d:interrupted in socket send\n",armci_me);
 
491
         }
 
492
         goto again;
 
493
      }else{
 
494
 
 
495
         if(DEBUG_){
 
496
           (void) fprintf(stderr,"sock=%d, pid=%d, nsent=%d, len=%d\n",
 
497
                        sock, armci_me, nsent, lenbuf);
 
498
           (void) fflush(stderr);
 
499
         }
 
500
        status = -1; break;
 
501
      }
 
502
    }
 
503
 
 
504
    buf += nsent;
 
505
    lenbuf -= nsent;
 
506
  }
 
507
 
 
508
  return status;
 
509
}
 
510
 
 
511
 
 
512
 
 
513
void armci_CreateSocketAndBind(int *sock, int *port)
 
514
/*
 
515
  Create a socket, bind it to a wildcard internet name and return
 
516
  the info so that its port number may be advertised
 
517
*/
 
518
{
 
519
  soclen_t  length;
 
520
  struct sockaddr_in server;
 
521
  int size = PACKET_SIZE;
 
522
  int on = 1;
 
523
 
 
524
  length = sizeof (struct sockaddr_in);
 
525
 
 
526
  /* Create socket */
 
527
 
 
528
  if ( (*sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
 
529
    armci_die("armci_CreateSocketAndBind: socket creation failed",  *sock);
 
530
 
 
531
  if(setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof on) == -1)
 
532
        armci_die("armci_CreateSocketAndBind: error from setsockopt",  -1);
 
533
 
 
534
  /* Increase size of socket buffers to improve long message
 
535
     performance and increase size of message that goes asynchronously */
 
536
 
 
537
  if(setsockopt(*sock, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof(size)))
 
538
    armci_die("armci_CreateSocketAndBind: error setting SO_RCVBUF", size);
 
539
  if(setsockopt(*sock, SOL_SOCKET, SO_SNDBUF, (char *) &size, sizeof(size)))
 
540
    armci_die("armci_CreateSocketAndBind: error setting SO_SNDBUF", size);
 
541
 
 
542
  armci_TcpNoDelay(*sock);
 
543
 
 
544
  /* Name socket with wildcards */
 
545
 
 
546
  server.sin_family = AF_INET;
 
547
  server.sin_addr.s_addr = INADDR_ANY;
 
548
  server.sin_port = 0;
 
549
  if (bind(*sock, (struct sockaddr *) &server, length) < 0)
 
550
    armci_die("armci_CreateSocketAndBind: bind failed", 0);
 
551
 
 
552
  /* Find out port number etc. */
 
553
 
 
554
  if (getsockname(*sock, (struct sockaddr *) &server, &length) < 0)
 
555
    armci_die("armci_CreateSocketAndBind: getsockname failed",  0);
 
556
 
 
557
  *port = ntohs(server.sin_port);
 
558
 
 
559
}
 
560
 
 
561
 
 
562
/*\ listen for socket connections
 
563
\*/
 
564
void armci_ListenSockAll(int* socklist, int num)
 
565
{
 
566
int i;
 
567
 
 
568
  if(num<0)armci_die("armci_ListenSockAll invalid number of sockets",num);
 
569
 
 
570
  for(i=0; i< num; i++){
 
571
     againlist:
 
572
       if (listen(socklist[i], num) < 0) {
 
573
         if (errno == EINTR)
 
574
           goto againlist;
 
575
         else
 
576
           armci_die("armci_ListenSockAll: listen failed",  0);
 
577
       }
 
578
  }
 
579
 
 
580
  if (DEBUG_) {
 
581
    (void) printf("process %d out of listen on %d sockets\n",armci_me,num);
 
582
    (void) fflush(stdout);
 
583
  }
 
584
}
 
585
 
 
586
void armci_tcp_get_sock_buf_size(int msgsock){
 
587
 int buffer_orig=32768,r;
 
588
 r = -1;
 
589
 while ( r < 0 && (tcp_sendrcv_bufsize > buffer_orig) ) {
 
590
 
 
591
  r= setsockopt(msgsock, SOL_SOCKET, SO_SNDBUF, (char *) &tcp_sendrcv_bufsize, sizeof(tcp_sendrcv_bufsize));
 
592
  r= setsockopt(msgsock, SOL_SOCKET, SO_RCVBUF, (char *) &tcp_sendrcv_bufsize, sizeof(tcp_sendrcv_bufsize));
 
593
  if( r < 0 ) tcp_sendrcv_bufsize =(tcp_sendrcv_bufsize/2);
 
594
  }
 
595
}
 
596
 
 
597
/*\  accept connections on the specified sockets
 
598
\*/
 
599
void armci_AcceptSockAll(int* socklist, int num)
 
600
{
 
601
  fd_set ready, fdzero;
 
602
  struct timeval timelimit;
 
603
  int maxsock, msgsock, nready, num_accept=0;
 
604
  int i;
 
605
 
 
606
  if(num<0)armci_die("armci_AcceptSockAll invalid number of sockets",num);
 
607
 
 
608
  /* Use select to wait for someone to try and establish a connection
 
609
     so that we can add a short timeout to avoid hangs */
 
610
 
 
611
  FD_ZERO(&fdzero);
 
612
 
 
613
againsel:
 
614
  FD_ZERO(&ready);
 
615
 
 
616
  /* we negate socket number on the list to mark already connected */
 
617
  maxsock=0;
 
618
  for(i=0; i<num; i++){
 
619
     if(socklist[i] > maxsock)maxsock = socklist[i]; /* find largest value*/
 
620
     if(socklist[i]>0) FD_SET(socklist[i], &ready);
 
621
/*     printf("%d: accepting socket%d=%d of %d\n",armci_me,i,socklist[i],num);*/
 
622
  }
 
623
 
 
624
  timelimit.tv_sec = TIMEOUT_ACCEPT;
 
625
  timelimit.tv_usec = 0;
 
626
  nready = select(maxsock+1, &ready, (fd_set *) NULL, (fd_set *) NULL,
 
627
                  &timelimit);
 
628
 
 
629
  /* error screening */
 
630
  if ( (nready <= 0) && (errno == EINTR) )
 
631
    goto againsel;
 
632
  else if (nready < 0)
 
633
    armci_die("armci_AcceptSockAll: error from select",nready);
 
634
  else if (nready == 0)
 
635
    armci_die("armci_AcceptSockAll:timeout waiting for connection",nready);
 
636
 
 
637
/*  if (bcmp(&ready,&fdzero,sizeof(fdzero)))*/
 
638
/*    armci_die("armci_AcceptSockAll: out of select but not ready!",nready);*/
 
639
 
 
640
  /* accept connection from newly contacted clients */
 
641
  for(i=0; i< num; i++){ 
 
642
    int sock = socklist[i];
 
643
    if(sock<0) continue; /* accepted already */
 
644
    if(!FD_ISSET(sock, &ready)) continue; /* not contacted yet */
 
645
 
 
646
    againacc:
 
647
 
 
648
      msgsock = accept(sock, (struct sockaddr *) NULL, (soclen_t *) NULL);
 
649
      if(msgsock==0){
 
650
        int msgsock2;
 
651
        msgsock2 = dup(msgsock);
 
652
        /*(void) CLOSE(msgsock);*/
 
653
        msgsock = msgsock2;
 
654
      }
 
655
 
 
656
      if (msgsock == -1) {
 
657
        if (errno == EINTR)
 
658
          goto againacc;
 
659
        else
 
660
          armci_die("armci_AcceptSockAll: accept failed",  msgsock);
 
661
      }
 
662
 
 
663
    if(DEBUG_){
 
664
       (void) printf("process %d out of accept socket=%d\n",armci_me,msgsock);
 
665
       (void) fflush(stdout);
 
666
    }
 
667
 
 
668
    /* Increase size of socket buffers to improve long message
 
669
       performance and increase size of message that goes asynchronously */
 
670
armci_tcp_get_sock_buf_size(msgsock);     
 
671
 
 
672
    armci_TcpNoDelay(msgsock);
 
673
 
 
674
    (void) CLOSE(sock); /* will not be needing this again */
 
675
 
 
676
    socklist[i] = -msgsock; /* negate connected socket on the list */
 
677
 
 
678
    num_accept++;
 
679
  }
 
680
 
 
681
  if(num_accept < num)
 
682
     goto againsel;
 
683
 
 
684
  for(i=0; i< num; i++) 
 
685
     if(socklist[i]>=0)
 
686
        armci_die("armci_AcceptSockAll: not connected",socklist[i]);
 
687
     else
 
688
        socklist[i] = - socklist[i];
 
689
 
 
690
}
 
691
 
 
692
 
 
693
int armci_ListenAndAccept(int sock)
 
694
/*
 
695
  Listen and accept a connection on the specified socket
 
696
  which was created with CreateSocketAndBind
 
697
*/
 
698
{
 
699
  fd_set ready;
 
700
  struct timeval timelimit;
 
701
  int msgsock, nready;
 
702
  int size = PACKET_SIZE;
 
703
  
 
704
againlist:
 
705
  if (listen(sock, 1) < 0) {
 
706
    if (errno == EINTR)
 
707
      goto againlist;
 
708
    else
 
709
      armci_die("armci_ListenAndAccept: listen failed",  0);
 
710
  }
 
711
 
 
712
  if (DEBUG_) {
 
713
    (void) printf("process %d out of listen on socket %d\n",armci_me,sock);
 
714
    (void) fflush(stdout);
 
715
  }
 
716
 
 
717
  /* Use select to wait for someone to try and establish a connection
 
718
     so that we can add a short timeout to avoid hangs */
 
719
 
 
720
againsel:
 
721
  FD_ZERO(&ready);
 
722
  FD_SET(sock, &ready);
 
723
 
 
724
  timelimit.tv_sec = TIMEOUT_ACCEPT;
 
725
  timelimit.tv_usec = 0;
 
726
  nready = select(sock+1, &ready, (fd_set *) NULL, (fd_set *) NULL,
 
727
                  &timelimit);
 
728
  if ( (nready <= 0) && (errno == EINTR) )
 
729
    goto againsel;
 
730
  else if (nready < 0)
 
731
    armci_die("armci_ListenAndAccept: error from select",  nready);
 
732
  else if (nready == 0)
 
733
    armci_die("armci_ListenAndAccept: timeout waiting for connection", nready);
 
734
 
 
735
  if (!FD_ISSET(sock, &ready))
 
736
    armci_die("armci_ListenAndAccept: out of select but not ready!",  nready);
 
737
 
 
738
againacc:
 
739
  msgsock = accept(sock, (struct sockaddr *) NULL, (soclen_t *) NULL);
 
740
  if (msgsock == -1) {
 
741
    if (errno == EINTR)
 
742
      goto againacc;
 
743
    else
 
744
      armci_die("armci_ListenAndAccept: accept failed",  msgsock);
 
745
  }
 
746
 
 
747
  if (DEBUG_) {
 
748
    (void) printf("process %d out of accept on socket %d\n", armci_me,msgsock);
 
749
    (void) fflush(stdout);
 
750
  }
 
751
 
 
752
  /* Increase size of socket buffers to improve long message
 
753
     performance and increase size of message that goes asynchronously */
 
754
 
 
755
  if(setsockopt(msgsock, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof size))
 
756
    armci_die("armci_ListenAndAccept: error setting SO_RCVBUF",  size);
 
757
  if(setsockopt(msgsock, SOL_SOCKET, SO_SNDBUF, (char *) &size, sizeof size))
 
758
    armci_die("armci_ListenAndAccept: error setting SO_SNDBUF",  size);
 
759
 
 
760
  armci_TcpNoDelay(sock);
 
761
 
 
762
  (void) CLOSE(sock);     /* will not be needing this again */
 
763
  return msgsock;
 
764
}
 
765
 
 
766
 
 
767
int armci_CreateSocketAndConnect(char *hostname, int port)
 
768
/*
 
769
  Return the file descriptor of the socket which connects me to the
 
770
  remote process on hostname at port 
 
771
 
 
772
  hostname = hostname of the remote process
 
773
  port     =  port number of remote socket
 
774
*/
 
775
{
 
776
  int sock, status;
 
777
  struct sockaddr_in server;
 
778
  struct hostent *hp;
 
779
  int on = 1;
 
780
  int trial;
 
781
#if !defined(SGI) && !defined(WIN32)
 
782
  struct hostent *gethostbyname();
 
783
#endif
 
784
 
 
785
  /* Create socket */
 
786
 
 
787
  if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
 
788
    (void) fprintf(stderr,"trying to connect to host=%s, port=%d\n",
 
789
                   hostname, port);
 
790
    armci_die("armci_CreateSocketAndConnect: socket failed",  sock);
 
791
  }
 
792
 
 
793
  /* the following can be disabled */
 
794
  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, 
 
795
                 (char *) &on, sizeof on) == -1)
 
796
        armci_die("armci_CreateSocketAndConnect: error setting REUSEADDR",  -1);
 
797
 
 
798
  /* Connect socket */
 
799
  server.sin_family = AF_INET;
 
800
  hp = gethostbyname(hostname);
 
801
  if (hp == 0) {
 
802
    (void) fprintf(stderr,"trying to connect to host=%s, port=%d\n",
 
803
                   hostname, port);
 
804
    armci_die("armci_CreateSocketAndConnect: gethostbyname failed", 0);
 
805
  }
 
806
 
 
807
  bcopy((char *) hp->h_addr, (char *) &server.sin_addr, hp->h_length);
 
808
  server.sin_port = htons((unsigned short) port);
 
809
 
 
810
  trial = 0;
 
811
againcon:
 
812
  if ((status = 
 
813
     connect(sock, (struct sockaddr *) &server, sizeof server)) < 0) {
 
814
    if (errno == EINTR)
 
815
      goto againcon;
 
816
    else if(trial>CONNECT_TRIALS){
 
817
      
 
818
           (void) fprintf(stderr,"%d:trying connect to host=%s, port=%d t=%d %d\n",
 
819
                   armci_me,hostname, port,trial,errno);
 
820
           perror("trying to connect:");
 
821
           armci_die("armci_CreateSocketAndConnect: connect failed", status);
 
822
       }else {
 
823
 
 
824
         trial++;
 
825
         sleep(1);
 
826
         goto againcon;
 
827
       }
 
828
  }
 
829
  
 
830
  /* Increase size of socket buffers to improve long message
 
831
     performance and increase size of message that goes asynchronously */
 
832
 
 
833
  armci_tcp_get_sock_buf_size(sock); 
 
834
  armci_TcpNoDelay(sock);
 
835
 
 
836
  return sock;
 
837
}
 
838