src/sock_fd.h
author Tero Marttila <terom@fixme.fi>
Fri, 24 Apr 2009 23:01:34 +0300
changeset 153 d35e7cb3a489
parent 118 05b8d5150313
permissions -rw-r--r--
implement irc_net reconnect, requires testing
#ifndef SOCK_FD_H
#define SOCK_FD_H
/**
 * @file
 *
 * A generic sock_stream implementation for normal POSIX file descriptor based byte streams.
 */
#include "sock_internal.h"
#include <event2/event.h>
#include <stdbool.h>

/**
 * The fd-based sock_stream base implementation
 */
struct sock_fd {
    /** The base struct for sock_stream_* functions */
    struct sock_stream base;
    
    /** The OS file descriptor */
    int fd;

    /** The callback and arg used for sock_fd_init_ev - required for sock_fd_set */
    void (*ev_cb) (evutil_socket_t, short, void *);
    void *ev_arg;

    /** The IO events */
    struct event *ev_read, *ev_write;

};

/**
 * Get a sock_stream pointer from a sock_fd
 */
#define SOCK_FD_BASE(sock_ptr) (&(sock_ptr)->base)

/**
 * Get the sock_stream.err pointer from a sock_fd
 */
#define SOCK_FD_ERR(sock_ptr) SOCK_ERR(SOCK_FD_BASE(sock_ptr))



/**
 * Callback suitable for use with sock_fd_init_ev, which just invoke's the sock_stream's callbacks as appropriate.
 */
void sock_fd_event_handler (evutil_socket_t fd, short what, void *arg);

/**
 * sock_stream_methods::read implementation.
 */
err_t sock_fd_read (struct sock_stream *base_sock, void *buf, size_t *len, struct error_info *err);

/**
 * sock_stream_methods::write implementation.
 */
err_t sock_fd_write (struct sock_stream *base_sock, const void *buf, size_t *len, struct error_info *err);

/**
 * sock_stream_methods::event_init implementation.
 */
err_t sock_fd_event_init (struct sock_stream *base_sock);

/**
 * sock_stream_methods::event_enable implementation.
 */
err_t sock_fd_event_enable (struct sock_stream *base_sock, short mask);



/**
 * Initialize the sock_fd with the given fd, or -1, if no valid fd yet.
 */
void sock_fd_init (struct sock_fd *sock, int fd);

/**
 * Set the socket's nonblock mode. This should not do anything (apart from an extraneous syscall) if non-blocking
 * mode is already set.
 */
err_t sock_fd_set_nonblock (struct sock_fd *sock, bool nonblock);

/**
 * Initialize sock_fd.ev_* to use the socket's fd with the given callback. The ev's are not activated yet.
 *
 * The sock_fd must *not* have any ev's set.
 */
err_t sock_fd_init_ev (struct sock_fd *sock, void (*ev_cb) (evutil_socket_t, short, void *), void *arg);

/**
 * event_add the specified ev_* events, so they are enabled and the callback will be executed.
 */
err_t sock_fd_enable_events (struct sock_fd *sock, short mask);

/**
 * The opposite of init_ev, this clears any set events, so that they can be re-initialized with init_ev.
 */
void sock_fd_deinit_ev (struct sock_fd *sock);

/**
 * Update a sock_fd's fd, also updating any events set with sock_fd_init_ev. If any events were enabled before, they
 * are not enabled anymore.
 */
err_t sock_fd_set (struct sock_fd *sock, int fd);

/**
 * Close an opened sock_fd, restoring it to a state suitable for sock_fd_init
 */
err_t sock_fd_close (struct sock_fd *sock);



#endif