aboutsummaryrefslogtreecommitdiffstats
path: root/android/sync-utils.h
blob: bb54f3cfbb62a743a9bf2147a7d35d28e56886d0 (plain)
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
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Contains helper routines dealing with syncronous access to a non-blocking
 * sokets.
 */

#ifndef ANDROID_SYNC_UTILS_H
#define ANDROID_SYNC_UTILS_H

#include "android/android.h"
#include "sockets.h"

/* Descriptor for a connected non-blocking socket providing synchronous I/O */
typedef struct SyncSocket SyncSocket;

/*
 * Connect to a non-blocking socket for further synchronous I/O.
 * Note: this routine will explicitly call socket_set_nonblock on the fd passed
 * to this routine.
 * Param:
 *  fd - File descriptor for the socket, created with socket_create_xxx routine.
 *  sockaddr - Address of the socket to connect to.
 *  timeout - Time out (in milliseconds) to wait for the connection to occur.
 * Return:
 *  Initialized SyncSocket descriptor on success, or NULL on failure.
 */
SyncSocket* syncsocket_connect(int fd, SockAddress* sockaddr, int timeout);

/*
 * Initializes a non-blocking socket for further synchronous I/O.
 * Note: this routine will explicitly call socket_set_nonblock on the fd passed
 * to this routine.
 * Param:
 *  fd - File descriptor for the already connected socket.
 * Return:
 *  Initialized SyncSocket descriptor on success, or NULL on failure.
 */
SyncSocket* syncsocket_init(int fd);

/*
 * Closes SyncSocket descriptor obtained from syncsocket_connect routine.
 * Param:
 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
 */
void syncsocket_close(SyncSocket* ssocket);

/*
 * Frees memory allocated for SyncSocket descriptor obtained from
 * syncsocket_connect routine. Note that this routine will also close socket
 * connection.
 * Param:
 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
 */
void syncsocket_free(SyncSocket* ssocket);

/*
 * Prepares the socket for read.
 * Note: this routine must be called before calling into syncsocket_read_xxx
 * routines.
 * Param:
 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
 * Return:
 *  0 on success, or -1 on failure.
 */
int syncsocket_start_read(SyncSocket* ssocket);

/*
 * Clears the socket after reading.
 * Note: this routine must be called after all expected data has been read from
 * the socket.
 * Param:
 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
 * Return:
 *  0 on success, or -1 on failure.
 */
int syncsocket_stop_read(SyncSocket* ssocket);

/*
 * Prepares the socket for write.
 * Note: this routine must be called before calling into syncsocket_write_xxx
 * routines.
 * Param:
 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
 * Return:
 *  0 on success, or -1 on failure.
 */
int syncsocket_start_write(SyncSocket* ssocket);

/*
 * Clears the socket after writing.
 * Note: this routine must be called after all data has been written to the
 * socket.
 * Param:
 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
 * Return:
 *  0 on success, or -1 on failure.
 */
int syncsocket_stop_write(SyncSocket* ssocket);

/*
 * Synchronously reads from the socket.
 * Note: syncsocket_start_read must be called before first call to this routine.
 * Once syncsocket_start_read has been called, multiple syncsocket_read_xxx can
 * be called to read all necessary data from the socket. When all necessary data
 * has been read, syncsocket_stop_read must be called.
 * Param:
 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
 *  buf - Buffer where to read data.
 *  size - Number of bytes to read.
 *  deadline - Absoulte deadline time to complete the reading.
 * Return:
 *  Number of bytes read on success, or -1 on failure.
 */
ssize_t syncsocket_read_absolute(SyncSocket* ssocket,
                                 void* buf,
                                 size_t size,
                                 int64_t deadline);

/*
 * Synchronously reads from the socket.
 * Note: syncsocket_start_read must be called before first call to this routine.
 * Once syncsocket_start_read has been called, multiple syncsocket_read_xxx can
 * be called to read all necessary data from the socket. When all necessary data
 * has been read, syncsocket_stop_read must be called.
 * Param:
 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
 *  buf - Buffer where to read data.
 *  size - Number of bytes to read.
 *  timeout - Timeout (in milliseconds) to complete the reading.
 * Return:
 *  Number of bytes read on success, or -1 on failure.
 */
ssize_t syncsocket_read(SyncSocket* ssocket, void* buf, size_t size, int timeout);

/*
 * Synchronously writes to the socket.
 * Note: syncsocket_start_write must be called before first call to this routine.
 * Once syncsocket_start_write has been called, multiple syncsocket_write_xxx can
 * be called to write all necessary data to the socket. When all necessary data
 * has been written, syncsocket_stop_write must be called.
 * Param:
 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
 *  buf - Buffer containing data to write.
 *  size - Number of bytes to write.
 *  deadline - Absoulte deadline time to complete the writing.
 * Return:
 *  Number of bytes written on success,or -1 on failure.
 */
ssize_t syncsocket_write_absolute(SyncSocket* ssocket,
                                  const void* buf,
                                  size_t size,
                                  int64_t deadline);

/*
 * Synchronously writes to the socket.
 * Note: syncsocket_start_write must be called before first call to this routine.
 * Once syncsocket_start_write has been called, multiple syncsocket_write_xxx can
 * be called to write all necessary data to the socket. When all necessary data
 * has been written, syncsocket_stop_write must be called.
 * Param:
 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
 *  buf - Buffer containing data to write.
 *  size - Number of bytes to write.
 *  timeout - Timeout (in milliseconds) to complete the writing.
 * Return:
 *  Number of bytes written on success, or -1 on failure.
 */
ssize_t syncsocket_write(SyncSocket* ssocket,
                         const void* buf,
                         size_t size,
                         int timeout);

/*
 * Synchronously reads a line terminated with '\n' from the socket.
 * Note: syncsocket_start_read must be called before first call to this routine.
 * Param:
 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
 *  buffer - Buffer where to read line.
 *  size - Number of characters the buffer can contain.
 *  deadline - Absoulte deadline time to complete the reading.
 * Return:
 *  Number of chracters read on success, 0 on deadline expiration,
 *  or -1 on failure.
 */
ssize_t syncsocket_read_line_absolute(SyncSocket* ssocket,
                                      char* buffer,
                                      size_t size,
                                      int64_t deadline);

/*
 * Synchronously reads a line terminated with '\n' from the socket.
 * Note: syncsocket_start_read must be called before first call to this routine.
 * Param:
 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
 *  buffer - Buffer where to read line.
 *  size - Number of characters the buffer can contain.
 *  timeout - Timeout (in milliseconds) to complete the reading.
 * Return:
 *  Number of chracters read on success, 0 on deadline expiration,
 *  or -1 on failure.
 */
ssize_t syncsocket_read_line(SyncSocket* ssocket,
                             char* buffer,
                             size_t size,
                             int timeout);

/* Gets socket descriptor associated with the sync socket.
 * Param:
 *  ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
 * Return
 *  Socket descriptor associated with the sync socket.
 */
int syncsocket_get_socket(SyncSocket* ssocket);

/* Converts syncsocket_xxx operation status into success / failure result.
 * Param:
 *  status - syncsocket_xxx operation status to convert.
 * Return:
 *  0 if status passed to this routine indicated a success, or < 0 if status
 *  indicated a failure.
 */
static inline int
syncsocket_result(int status)
{
    if (status == 0) {
        // Status 0 returned from syncsocket_xxx means "disconnection", which is
        // a failure.
        status = -1;
    } else if (status > 0) {
        // Status > 0 means success.
        status = 0;
    }
    return status;
}

#endif  // ANDROID_SYNC_UTILS_H