socket-collection-epoll.h 3.26 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
/*
 * (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_EPOLL_H
#define __SOCKET_COLLECTION_EPOLL_H

#include <assert.h>
#include <sys/epoll.h>

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

#define BMI_EPOLL_MAX_PER_CYCLE 16

struct socket_collection
{
    int epfd;
    
    struct epoll_event event_array[BMI_EPOLL_MAX_PER_CYCLE];

    int server_socket;
38
    int server_port;
Dries Kimpe's avatar
Dries Kimpe committed
39 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
};
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);

/* the bmi_tcp code may try to add a socket to the collection before
 * it is fully connected, just ignore in this case
 */
#define BMI_socket_collection_add(s, m) \
do { \
    struct tcp_addr* tcp_data = (m)->method_data; \
    if(tcp_data->socket > -1){ \
        struct epoll_event event;\
        memset(&event, 0, sizeof(event));\
        event.events = EPOLLIN|EPOLLERR|EPOLLHUP;\
        event.data.ptr = tcp_data->map;\
        epoll_ctl(s->epfd, EPOLL_CTL_ADD, tcp_data->socket, &event);\
    } \
} while(0)

#define BMI_socket_collection_remove(s, m) \
do { \
    struct epoll_event event;\
    struct tcp_addr* tcp_data = (m)->method_data; \
    tcp_data->write_ref_count = 0; \
    memset(&event, 0, sizeof(event));\
    event.events = 0;\
    event.data.ptr = tcp_data->map;\
    epoll_ctl(s->epfd, EPOLL_CTL_DEL, tcp_data->socket, &event);\
} 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 { \
    struct tcp_addr* tcp_data = (m)->method_data; \
    struct epoll_event event;\
    assert(tcp_data->socket > -1); \
    tcp_data->write_ref_count++; \
    memset(&event, 0, sizeof(event));\
    event.events = EPOLLIN|EPOLLERR|EPOLLHUP|EPOLLOUT;\
    event.data.ptr = tcp_data->map;\
    epoll_ctl(s->epfd, EPOLL_CTL_MOD, tcp_data->socket, &event);\
} while(0)

#define BMI_socket_collection_remove_write_bit(s, m) \
do { \
    struct tcp_addr* tcp_data = (m)->method_data; \
    struct epoll_event event;\
    tcp_data->write_ref_count--; \
    assert(tcp_data->write_ref_count > -1); \
    if (tcp_data->write_ref_count == 0) { \
        memset(&event, 0, sizeof(event));\
        event.events = EPOLLIN|EPOLLERR|EPOLLHUP;\
        event.data.ptr = tcp_data->map;\
        epoll_ctl(s->epfd, EPOLL_CTL_MOD, tcp_data->socket, &event);\
    }\
} 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_EPOLL_H */

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