| 1 | /*
|
|---|
| 2 | * (C) 2001 Clemson University and The University of Chicago
|
|---|
| 3 | *
|
|---|
| 4 | * See COPYING in top-level directory.
|
|---|
| 5 | */
|
|---|
| 6 |
|
|---|
| 7 | /*
|
|---|
| 8 | * This file contains the visible data structures and function interface
|
|---|
| 9 | * for a socket collection library. This library can maintain lists of
|
|---|
| 10 | * sockets and perform polling operations on them.
|
|---|
| 11 | */
|
|---|
| 12 |
|
|---|
| 13 | /*
|
|---|
| 14 | * NOTE: I am making read bits implicit in the implementation. A poll
|
|---|
| 15 | * will always check to see if there is data to be read on a socket.
|
|---|
| 16 | */
|
|---|
| 17 |
|
|---|
| 18 | #ifndef __SOCKET_COLLECTION_H
|
|---|
| 19 | #define __SOCKET_COLLECTION_H
|
|---|
| 20 |
|
|---|
| 21 | #include <assert.h>
|
|---|
| 22 | #include "bmi-method-support.h"
|
|---|
| 23 | #include "bmi-tcp-addressing.h"
|
|---|
| 24 | #include "quicklist.h"
|
|---|
| 25 | #include "gen-locks.h"
|
|---|
| 26 |
|
|---|
| 27 | struct socket_collection
|
|---|
| 28 | {
|
|---|
| 29 | struct pollfd* pollfd_array;
|
|---|
| 30 | bmi_method_addr_p* addr_array;
|
|---|
| 31 | int array_max;
|
|---|
| 32 | int array_count;
|
|---|
| 33 |
|
|---|
| 34 | gen_mutex_t queue_mutex;
|
|---|
| 35 | struct qlist_head remove_queue;
|
|---|
| 36 | struct qlist_head add_queue;
|
|---|
| 37 |
|
|---|
| 38 | int server_socket;
|
|---|
| 39 | int pipe_fd[2];
|
|---|
| 40 | };
|
|---|
| 41 | typedef struct socket_collection* socket_collection_p;
|
|---|
| 42 |
|
|---|
| 43 | enum
|
|---|
| 44 | {
|
|---|
| 45 | SC_READ_BIT = 1,
|
|---|
| 46 | SC_WRITE_BIT = 2,
|
|---|
| 47 | SC_ERROR_BIT = 4
|
|---|
| 48 | };
|
|---|
| 49 |
|
|---|
| 50 | socket_collection_p BMI_socket_collection_init(int new_server_socket);
|
|---|
| 51 | void BMI_socket_collection_queue(socket_collection_p scp,
|
|---|
| 52 | bmi_method_addr_p map, struct qlist_head* queue);
|
|---|
| 53 |
|
|---|
| 54 | /* the bmi_tcp code may try to add a socket to the collection before
|
|---|
| 55 | * it is fully connected, just ignore in this case
|
|---|
| 56 | */
|
|---|
| 57 | /* write a byte on the pipe_fd[1] so that poll breaks out in case it is idling */
|
|---|
| 58 | #define BMI_socket_collection_add(s, m) \
|
|---|
| 59 | do { \
|
|---|
| 60 | struct tcp_addr* tcp_data = (struct tcp_addr *) (m)->method_data; \
|
|---|
| 61 | if(tcp_data->socket > -1){ \
|
|---|
| 62 | char c; \
|
|---|
| 63 | gen_mutex_lock(&((s)->queue_mutex)); \
|
|---|
| 64 | BMI_socket_collection_queue(s, m, &((s)->add_queue)); \
|
|---|
| 65 | gen_mutex_unlock(&((s)->queue_mutex)); \
|
|---|
| 66 | write(s->pipe_fd[1], &c, 1);\
|
|---|
| 67 | } \
|
|---|
| 68 | } while(0)
|
|---|
| 69 |
|
|---|
| 70 | #define BMI_socket_collection_remove(s, m) \
|
|---|
| 71 | do { \
|
|---|
| 72 | char c;\
|
|---|
| 73 | gen_mutex_lock(&((s)->queue_mutex)); \
|
|---|
| 74 | BMI_socket_collection_queue(s, m, &((s)->remove_queue)); \
|
|---|
| 75 | gen_mutex_unlock(&((s)->queue_mutex)); \
|
|---|
| 76 | write(s->pipe_fd[1], &c, 1);\
|
|---|
| 77 | } while(0)
|
|---|
| 78 |
|
|---|
| 79 | /* we _must_ have a valid socket at this point if we want to write data */
|
|---|
| 80 | #define BMI_socket_collection_add_write_bit(s, m) \
|
|---|
| 81 | do { \
|
|---|
| 82 | char c;\
|
|---|
| 83 | struct tcp_addr* tcp_data = (struct tcp_addr *) (m)->method_data; \
|
|---|
| 84 | assert(tcp_data->socket > -1); \
|
|---|
| 85 | gen_mutex_lock(&((s)->queue_mutex)); \
|
|---|
| 86 | tcp_data->write_ref_count++; \
|
|---|
| 87 | BMI_socket_collection_queue((s),(m), &((s)->add_queue)); \
|
|---|
| 88 | gen_mutex_unlock(&((s)->queue_mutex)); \
|
|---|
| 89 | _write(s->pipe_fd[1], &c, 1);\
|
|---|
| 90 | } while(0)
|
|---|
| 91 |
|
|---|
| 92 | #define BMI_socket_collection_remove_write_bit(s, m) \
|
|---|
| 93 | do { \
|
|---|
| 94 | char c;\
|
|---|
| 95 | struct tcp_addr* tcp_data = (struct tcp_addr *) (m)->method_data; \
|
|---|
| 96 | gen_mutex_lock(&((s)->queue_mutex)); \
|
|---|
| 97 | tcp_data->write_ref_count--; \
|
|---|
| 98 | assert(tcp_data->write_ref_count > -1); \
|
|---|
| 99 | BMI_socket_collection_queue((s),(m), &((s)->add_queue)); \
|
|---|
| 100 | gen_mutex_unlock(&((s)->queue_mutex)); \
|
|---|
| 101 | _write(s->pipe_fd[1], &c, 1);\
|
|---|
| 102 | } while(0)
|
|---|
| 103 |
|
|---|
| 104 | void BMI_socket_collection_finalize(socket_collection_p scp);
|
|---|
| 105 | int BMI_socket_collection_testglobal(socket_collection_p scp,
|
|---|
| 106 | int incount,
|
|---|
| 107 | int *outcount,
|
|---|
| 108 | bmi_method_addr_p * maps,
|
|---|
| 109 | int * status,
|
|---|
| 110 | int poll_timeout);
|
|---|
| 111 |
|
|---|
| 112 | #endif /* __SOCKET_COLLECTION_H */
|
|---|
| 113 |
|
|---|
| 114 | /*
|
|---|
| 115 | * Local variables:
|
|---|
| 116 | * c-indent-level: 4
|
|---|
| 117 | * c-basic-offset: 4
|
|---|
| 118 | * End:
|
|---|
| 119 | *
|
|---|
| 120 | * vim: ts=8 sts=4 sw=4 expandtab
|
|---|
| 121 | */
|
|---|