socket-collection.h 3.28 KB
Newer Older
Dries Kimpe's avatar
Dries Kimpe committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
/*
 * (C) 2001 Clemson University and The University of Chicago
 *
 * See COPYING in top-level directory.
 */

/*
 * This file contains the visible data structures and function interface
 * for a socket collection library.  This library can maintain lists of
 * sockets and perform polling operations on them.
 */

/*
 * NOTE:  I am making read bits implicit in the implementation.  A poll
 * will always check to see if there is data to be read on a socket.
 */

#ifndef __SOCKET_COLLECTION_H
#define __SOCKET_COLLECTION_H

#include <assert.h>
#include "bmi-method-support.h"
#include "bmi-tcp-addressing.h"
#include "quicklist.h"
#include "gen-locks.h"

struct socket_collection
{
    struct pollfd* pollfd_array;
    bmi_method_addr_p* addr_array;
    int array_max;
    int array_count;

    gen_mutex_t queue_mutex;
    struct qlist_head remove_queue;
    struct qlist_head add_queue;

    int server_socket;
39
    int server_port;
Dries Kimpe's avatar
Dries Kimpe committed
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
    int pipe_fd[2];
};
typedef struct socket_collection* socket_collection_p;

enum
{
    SC_READ_BIT = 1,
    SC_WRITE_BIT = 2,
    SC_ERROR_BIT = 4
};

socket_collection_p BMI_socket_collection_init(int new_server_socket);
void BMI_socket_collection_queue(socket_collection_p scp,
			   bmi_method_addr_p map, struct qlist_head* queue);

/* the bmi_tcp code may try to add a socket to the collection before
 * it is fully connected, just ignore in this case
 */
/* write a byte on the pipe_fd[1] so that poll breaks out in case it is idling */
#define BMI_socket_collection_add(s, m) \
do { \
    struct tcp_addr* tcp_data = (m)->method_data; \
    if(tcp_data->socket > -1){ \
        char c; \
	gen_mutex_lock(&((s)->queue_mutex)); \
	BMI_socket_collection_queue(s, m, &((s)->add_queue)); \
	gen_mutex_unlock(&((s)->queue_mutex)); \
        write(s->pipe_fd[1], &c, 1);\
    } \
} while(0)

#define BMI_socket_collection_remove(s, m) \
do { \
    char c;\
    gen_mutex_lock(&((s)->queue_mutex)); \
    BMI_socket_collection_queue(s, m, &((s)->remove_queue)); \
    gen_mutex_unlock(&((s)->queue_mutex)); \
    write(s->pipe_fd[1], &c, 1);\
} while(0)

/* we _must_ have a valid socket at this point if we want to write data */
#define BMI_socket_collection_add_write_bit(s, m) \
do { \
    char c;\
    struct tcp_addr* tcp_data = (m)->method_data; \
    assert(tcp_data->socket > -1); \
    gen_mutex_lock(&((s)->queue_mutex)); \
    tcp_data->write_ref_count++; \
    BMI_socket_collection_queue((s),(m), &((s)->add_queue)); \
    gen_mutex_unlock(&((s)->queue_mutex)); \
    write(s->pipe_fd[1], &c, 1);\
} while(0)

#define BMI_socket_collection_remove_write_bit(s, m) \
do { \
    char c;\
    struct tcp_addr* tcp_data = (m)->method_data; \
    gen_mutex_lock(&((s)->queue_mutex)); \
    tcp_data->write_ref_count--; \
    assert(tcp_data->write_ref_count > -1); \
    BMI_socket_collection_queue((s),(m), &((s)->add_queue)); \
    gen_mutex_unlock(&((s)->queue_mutex)); \
    write(s->pipe_fd[1], &c, 1);\
} while(0)

void BMI_socket_collection_finalize(socket_collection_p scp);
int BMI_socket_collection_testglobal(socket_collection_p scp,
				 int incount,
				 int *outcount,
				 bmi_method_addr_p * maps,
				 int * status,
				 int poll_timeout);

#endif /* __SOCKET_COLLECTION_H */

/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 * End:
 *
 * vim: ts=8 sts=4 sw=4 expandtab
 */