socket.h revision ed7095be083ffe47f8b9d0d3090b0f2e109b8125
1/******************************************************************************
2 *
3 *  Copyright (C) 2014 Google, Inc.
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19#pragma once
20
21#include <stddef.h>
22#include <stdint.h>
23
24#include "thread.h"
25
26typedef struct reactor_t reactor_t;
27typedef struct socket_t socket_t;
28typedef uint16_t port_t;
29
30typedef void (*socket_cb)(socket_t *socket, void *context);
31
32// Returns a new socket object. The socket is in an idle, disconnected state when
33// it is returned by this function. The returned object must be freed by calling
34// |socket_free|. Returns NULL on failure.
35socket_t *socket_new(void);
36
37// Frees a socket object created by |socket_new| or |socket_accept|. |socket| may
38// be NULL. If the socket was connected, it will be disconnected.
39void socket_free(socket_t *socket);
40
41// Puts |socket| in listening mode for incoming TCP connections on the specified
42// |port|. Returns true on success, false on failure (e.g. |port| is bound by
43// another socket). |socket| may not be NULL.
44bool socket_listen(const socket_t *socket, port_t port);
45
46// Blocks on a listening socket, |socket|, until a client connects to it. Returns
47// a connected socket on success, NULL on failure. The returned object must be
48// freed by calling |socket_free|. |socket| may not be NULL.
49socket_t *socket_accept(const socket_t *socket);
50
51// Reads up to |count| bytes from |socket| into |buf|. This function will not
52// block. This function returns a positive integer representing the number
53// of bytes copied into |buf| on success, 0 if the socket has disconnected,
54// and -1 on error. This function may return a value less than |count| if not
55// enough data is currently available. If this function returns -1, errno will also
56// be set (see recv(2) for possible errno values). If there were no bytes available
57// to be read, this function returns -1 and sets errno to EWOULDBLOCK. Neither
58// |socket| nor |buf| may be NULL.
59ssize_t socket_read(const socket_t *socket, void *buf, size_t count);
60
61// Writes up to |count| bytes from |buf| into |socket|. This function will not
62// block. Returns a positive integer representing the number of bytes written
63// to |socket| on success, 0 if the socket has disconnected, and -1 on error. This
64// function may return a value less than |count| if writing more bytes would result
65// in blocking. If this function returns -1, errno will also be set (see send(2) for
66// possible errno values). If no bytes could be written without blocking, this
67// function will return -1 and set errno to EWOULDBLOCK. Neither |socket| nor |buf|
68// may be NULL.
69ssize_t socket_write(const socket_t *socket, const void *buf, size_t count);
70
71// Registers |socket| with the |thread|. When the socket becomes readable, |read_cb|
72// will be called. When the socket becomes writeable, |write_cb| will be called. The
73// |context| parameter is passed, untouched, to each of the callback routines. Neither
74// |socket| nor |thread| may be NULL. |read_cb| or |write_cb|, but not both, may be NULL.
75// |context| may be NULL.
76void socket_register(socket_t *socket, thread_t *thread, socket_cb read_cb, socket_cb write_cb, void *context);
77
78// Unregisters |socket| from whichever thread it is registered with, if any. This
79// function is idempotent.
80void socket_unregister(socket_t *socket);
81