Changeset 5556

Show
Ignore:
Timestamp:
07/14/12 11:49:53 (7 years ago)
Author:
nitin
Message:

Updated poll and select timeout.
Added unit tests for poll and select.

Location:
seattle/branches/nacl_repy/seattlelib
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • seattle/branches/nacl_repy/seattlelib/lind_net_calls.py

    r5544 r5556  
    12341234 
    12351235 
    1236 def select_syscall(nfds, readfds, writefds, exceptfds, time, nonblocking=False, notimer=False): 
     1236def select_syscall(nfds, readfds, writefds, exceptfds, time): 
    12371237  """  
    12381238    http://linux.die.net/man/2/select 
     
    12471247 
    12481248  retval = 0 
    1249  
     1249   
    12501250  # the bit vectors only support 1024 file descriptors, also lower FDs are not supported 
    12511251  if nfds < STARTINGFD or nfds > MAX_FD: 
     
    12571257 
    12581258  start_time = getruntime() 
    1259   end_time = start_time + time 
     1259  end_time = start_time + (time if time != None else -1) 
    12601260  while True: 
    12611261 
     
    13081308    assert not exceptfds, "Lind does not support exceptfds yet." 
    13091309 
    1310     # Only check once if we are non-blocking (passed a 0) 
    1311     # loop forever if we are notimer (pass a null) 
    1312     # or loop until we go past the end time 
    1313      
    1314     if retval != 0 or nonblocking or (not notimer and getruntime() >= end_time): 
     1310    # if the timeout is given as null or negative value, block forever until  
     1311    # an event has occured, if timeout is provided as zero, return immediatly. 
     1312    # if positive time provided, wait until time expires and return 
     1313     
     1314    if retval != 0 or time == 0 or (getruntime() >= end_time and time > 0): 
    13151315      break 
    13161316    else: 
     
    13651365  return_code = 0 
    13661366 
    1367   reply = [] 
    1368   for structpoll in fds: 
    1369     fd = structpoll['fd'] 
    1370     events = structpoll['events'] 
    1371     read = events & POLLIN > 0  
    1372     write = events & POLLOUT > 0  
    1373     err = events & POLLERR > 0 
    1374     reads = [] 
    1375     writes = [] 
    1376     errors = [] 
    1377     if read: 
    1378       reads.append(fd) 
    1379     if write: 
    1380       writes.append(fd) 
    1381     if err: 
    1382       errors.append(fd) 
    1383  
    1384     newfd = select_syscall(fd, reads, writes, errors, 0) 
    1385  
    1386     # this FD found something 
    1387     mask = 0 
    1388  
    1389     if newfd[0] > 0: 
    1390       mask = mask + (POLLIN if newfd[1] else 0) 
    1391       mask = mask + (POLLOUT if newfd[2] else 0)  
    1392       mask = mask + (POLLERR if newfd[3] else 0) 
    1393       return_code += 1 
    1394     structpoll['revents'] = mask 
     1367  endtime = getruntime() + timeout 
     1368  while True: 
     1369    for structpoll in fds: 
     1370      fd = structpoll['fd'] 
     1371      events = structpoll['events'] 
     1372      read = events & POLLIN > 0  
     1373      write = events & POLLOUT > 0  
     1374      err = events & POLLERR > 0 
     1375      reads = [] 
     1376      writes = [] 
     1377      errors = [] 
     1378      if read: 
     1379        reads.append(fd) 
     1380      if write: 
     1381        writes.append(fd) 
     1382      if err: 
     1383        errors.append(fd) 
     1384 
     1385      #select with timeout set to zero, acts as a poll...  
     1386      newfd = select_syscall(fd, reads, writes, errors, 0) 
     1387       
     1388      # this FD found something 
     1389      mask = 0 
     1390 
     1391      if newfd[0] > 0: 
     1392        mask = mask + (POLLIN if newfd[1] else 0) 
     1393        mask = mask + (POLLOUT if newfd[2] else 0)  
     1394        mask = mask + (POLLERR if newfd[3] else 0) 
     1395        return_code += 1 
     1396      structpoll['revents'] = mask 
     1397 
     1398    #if timeout is a negative value, then poll should run indefinitely 
     1399    #until there's an event in one of the descriptors. 
     1400    if (getruntime() > endtime and timeout >= 0) or return_code != 0: 
     1401      break 
     1402    else: 
     1403      sleep(RETRYWAITAMOUNT) 
     1404 
    13951405  return return_code, fds 
    1396  
    1397  
  • seattle/branches/nacl_repy/seattlelib/tests/ut_lind_net_poll.py

    r5540 r5556  
    1717lind_test_server._blank_fs_init() 
    1818 
    19 #Create a file, to read/write using poll. 
     19#Create a file, to read/write using select. 
    2020filefd = lind_test_server.open_syscall('/foo.txt', O_CREAT | O_EXCL | O_RDWR, S_IRWXA) 
    21   
    22 #Create a socket, to handle incomming connections. 
     21 
     22#Create 3 socket, one for server and two client sockets. 
    2323serversockfd = lind_test_server.socket_syscall(AF_INET, SOCK_STREAM, 0) 
    2424clientsockfd = lind_test_server.socket_syscall(AF_INET, SOCK_STREAM, 0) 
     
    2929lind_test_server.listen_syscall(serversockfd, 4) 
    3030 
    31 #Will contain list of sockets that poll needs to watch for. The first is 
    32 #the server socket for handling incomming new connections. 
    33  
     31#Register socket that needs to be polled, by default we provide server 
     32#socket and file descriptor, new client sockets will be added/removed 
     33#as and when server requires. 
    3434server_poll = {'fd': serversockfd, 
    3535                            'events': lind_test_server.POLLIN, 
    3636                            'revents': 0} 
    3737 
    38 client_poll = {'fd': clientsockfd, 
    39                             'events': lind_test_server.POLLIN, 
    40                             'revents': 0} 
     38file_poll = {'fd': filefd, 'events': lind_test_server.POLLIN, 'revents': 0} 
    4139 
    42 file_poll = {'fd': filefd, 
    43                             'events': lind_test_server.POLLIN | lind_test_server.POLLOUT, 
    44                             'revents': 0} 
    45  
    46 inputs = [file_poll, client_poll, server_poll] 
    47  
    48  
    49  
     40polled = [server_poll, file_poll] 
    5041 
    5142def process_request(): 
     
    5546  """ 
    5647  while True: 
    57     #Pass list of Inputs, Outputs for poll which returns if any activity 
     48    #Pass list of sockets that needs for polling which returns if any activity 
    5849    #occurs on any socket. 
    59     poll_vals = lind_test_server.poll_syscall(inputs, 0) 
    60     ret = [0,[],[],[]] 
     50    poll_vals = lind_test_server.poll_syscall(polled, 5) 
     51    ret = [poll_vals[0],[],[],[]] 
     52       
    6153    ret[1] = [x['fd'] for x in poll_vals[1] if x['revents'] & lind_test_server.POLLIN] 
    6254    ret[2] = [x['fd'] for x in poll_vals[1] if x['revents'] & lind_test_server.POLLOUT] 
     
    6961      if sock is serversockfd: 
    7062        newsockfd = lind_test_server.accept_syscall(sock) 
    71         try: 
    72           new_poll =  {'fd':newsockfd[2], 'events':lind_test_server.POLLIN|lind_test_server.POLLOUT, 'revents':0} 
    73           inputs.append(new_poll) 
    74         except Exception, e: 
    75           print "Note:", e 
     63        new_poll =  {'fd':newsockfd[2], 'events':lind_test_server.POLLIN, 'revents':0} 
     64        polled.append(new_poll) 
    7665      #Write to a file... 
    7766      elif sock is filefd: 
    78         assert lind_test_server.write_syscall(filefd, 'test') == 4, \ 
     67        assert lind_test_server.write_syscall(sock, 'test') == 4, \ 
    7968          "Failed to write into a file..." 
    80         lind_test_server.lseek_syscall(filefd,0,SEEK_SET) 
     69        lind_test_server.lseek_syscall(sock, 0, SEEK_SET) 
     70        #Once the write is successful into a file, Modify the file descriptor 
     71        #so that its ready for reading out of the file. 
     72        [x for x in polled if x['fd'] == sock][0]['events'] = \ 
     73          lind_test_server.POLLOUT 
    8174      #If the socket is in established conn., then we recv the data, if 
    8275      #there's no data, then close the client socket. 
     
    8477        data = lind_test_server.recv_syscall(sock, 100, 0) 
    8578        if data: 
    86           assert data == "test", "Recv failed in poll..." 
    87           #We make the ouput ready, so that it sends out data...  
    88           if len([x for x in inputs if x['fd'] == sock]) == 0: 
    89             inputs.append({'fd':sock, 'events':lind_test_server.POLLOUT,'revents':0}) 
    90         else:           
     79          assert data == "test", "Recv failed in select..." 
     80          #This socket is ready for writing, modify the socket descriptor 
     81          #to be in read-write mode. This socket can write data out to network  
     82          [x for x in polled if x['fd'] == sock][0]['events'] = \ 
     83            lind_test_server.POLLIN | lind_test_server.POLLOUT 
     84        else: 
     85          #No data means remote socket closed, hence close the client socket 
     86          #in server, also remove this socket from polling.     
    9187          lind_test_server.close_syscall(sock) 
    92           to_go = [x for x in inputs if x['fd'] == sock] 
    93           map(inputs.remove, to_go) 
     88          to_go = [x for x in polled if x['fd'] == sock] 
     89          map(polled.remove, to_go) 
    9490     
    9591    #Check for any activity in any of the output sockets... 
     
    9894        assert lind_test_server.read_syscall(sock, 4) == "test", \ 
    9995          "Failed to read from a file..." 
    100         to_go = [x for x in inputs if x['fd'] == sock] 
    101         map(inputs.remove, to_go) 
     96        #test for file finished, remove from polling. 
     97        to_go = [x for x in polled if x['fd'] == sock] 
     98        map(polled.remove, to_go) 
    10299      else: 
    103100        lind_test_server.send_syscall(sock, data, 0) 
    104         to_go = [x for x in inputs if x['fd'] == sock] 
    105         map(inputs.remove, to_go) 
    106  
    107  
     101        #Data is sent out of this socket, it's no longer ready for writing, 
     102        #modify it only read mode. 
     103        [x for x in polled if x['fd'] == sock][0]['events'] = \ 
     104          lind_test_server.POLLIN 
    108105 
    109106  lind_test_server.close_syscall(serversockfd) 
     
    119116  """ 
    120117  lind_test_server.connect_syscall(clientsockfd, '127.0.0.1', 50300) 
    121    
     118 
    122119  lind_test_server.send_syscall(clientsockfd, "test", 0) 
    123120  #Short sleeps are not working, give enough time... 
    124121  emultimer.sleep(1) 
    125   ret = lind_test_server.recv_syscall(clientsockfd, 100, 0) 
    126   assert ret  == "test", \ 
    127      "Write failed in poll while processing client 1... got:%s"%(str(ret)) 
     122  assert lind_test_server.recv_syscall(clientsockfd, 100, 0) == "test", \ 
     123     "Write failed in select while processing client 1..." 
    128124 
    129125  lind_test_server.close_syscall(clientsockfd) 
     
    141137emultimer.sleep(1) 
    142138assert lind_test_server.recv_syscall(client2sockfd, 100, 0) == "test", \ 
    143   "Write failed in poll while processing client 2..." 
     139  "Write failed in select while processing client 2..." 
    144140 
    145141lind_test_server.close_syscall(client2sockfd) 
     
    148144#loop... 
    149145emulmisc.exitall() 
     146 
  • seattle/branches/nacl_repy/seattlelib/tests/ut_lind_net_select.py

    r5537 r5556  
    2020filefd = lind_test_server.open_syscall('/foo.txt', O_CREAT | O_EXCL | O_RDWR, S_IRWXA) 
    2121  
    22 #Create a socket, to handle incomming connections. 
     22#Create 3 socket, one for server and two client sockets. 
    2323serversockfd = lind_test_server.socket_syscall(AF_INET, SOCK_STREAM, 0) 
    2424clientsockfd = lind_test_server.socket_syscall(AF_INET, SOCK_STREAM, 0) 
     
    2929lind_test_server.listen_syscall(serversockfd, 4) 
    3030 
    31 #Will contain list of sockets that select needs to watch for. The first is 
    32 #the server socket for handling incomming new connections. 
     31#Will contain list of sockets that select needs to watch for. By default we 
     32#provide server socket and file, new sockets will be added to monitor by server.  
    3333inputs = [serversockfd, filefd] 
    3434outputs = [filefd] 
     
    4343    #Pass list of Inputs, Outputs for select which returns if any activity 
    4444    #occurs on any socket. 
    45     ret = lind_test_server.select_syscall(11, inputs, outputs, excepts, 0, \ 
    46       notimer=True) 
     45    ret = lind_test_server.select_syscall(11, inputs, outputs, excepts, 5) 
    4746 
    4847    #Check for any activity in any of the Input sockets... 
     
    5554      #Write to a file... 
    5655      elif sock is filefd: 
    57         assert lind_test_server.write_syscall(filefd, 'test') == 4, \ 
     56        emultimer.sleep(1) 
     57        assert lind_test_server.write_syscall(sock, 'test') == 4, \ 
    5858          "Failed to write into a file..." 
    59         lind_test_server.lseek_syscall(filefd,0,SEEK_SET) 
     59        lind_test_server.lseek_syscall(sock, 0, SEEK_SET) 
    6060        inputs.remove(sock) 
    6161      #If the socket is in established conn., then we recv the data, if 
     
    6868          if sock not in outputs: 
    6969            outputs.append(sock) 
    70         else:           
     70        else:          
     71          #No data means remote socket closed, hence close the client socket 
     72          #in server, also remove this socket from readfd's.  
    7173          lind_test_server.close_syscall(sock) 
    7274          inputs.remove(sock) 
     
    7779        assert lind_test_server.read_syscall(sock, 4) == "test", \ 
    7880          "Failed to read from a file..." 
     81        #test for file finished, remove from monitoring. 
    7982        outputs.remove(sock) 
    8083      else: 
    8184        lind_test_server.send_syscall(sock, data, 0) 
     85        #Data is sent out this socket, it's no longer ready for writing 
     86        #remove this socket from writefd's.  
    8287        outputs.remove(sock) 
    8388