aboutsummaryrefslogtreecommitdiffstats
path: root/android/async-utils.h
diff options
context:
space:
mode:
authorDavid 'Digit' Turner <digit@android.com>2010-11-18 16:14:03 +0100
committerDavid 'Digit' Turner <digit@android.com>2010-11-19 15:01:21 +0100
commit6d448806a80bcc2557ae0a38e7fd206967cf844e (patch)
tree08c567d36949bbc4263eb7a84b67936ce7789f6d /android/async-utils.h
parent1bb627cd086588d3f9650fac04f4034961caf9f1 (diff)
downloadexternal_qemu-6d448806a80bcc2557ae0a38e7fd206967cf844e.zip
external_qemu-6d448806a80bcc2557ae0a38e7fd206967cf844e.tar.gz
external_qemu-6d448806a80bcc2557ae0a38e7fd206967cf844e.tar.bz2
Introduce asynchronous operation helpers.
<android/async-utils.h> contains generic helpers to read, write and connect to sockets. <android/async-console.h> contains a helper class to connect to Android console port asynchronously. Change-Id: I5d0a49a770ad974c5d4382438d75e9eb624368d1
Diffstat (limited to 'android/async-utils.h')
-rw-r--r--android/async-utils.h187
1 files changed, 187 insertions, 0 deletions
diff --git a/android/async-utils.h b/android/async-utils.h
new file mode 100644
index 0000000..e34e1bb
--- /dev/null
+++ b/android/async-utils.h
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ */
+#ifndef ANDROID_ASYNC_UTILS_H
+#define ANDROID_ASYNC_UTILS_H
+
+#include "android/looper.h"
+#include "sockets.h"
+
+/* A set of useful data types to perform asynchronous operations.
+ *
+ * IMPORTANT NOTE:
+ * In case of network disconnection, read() and write() just return 0
+ * the first time they are called. As a convenience, these functions
+ * will return ASYNC_ERROR and set 'errno' to ECONNRESET instead.
+ */
+typedef enum {
+ ASYNC_COMPLETE = 0, /* asynchronous operation completed */
+ ASYNC_ERROR, /* an error occurred, look at errno */
+ ASYNC_NEED_MORE /* more data is needed, try again later */
+} AsyncStatus;
+
+/* An AsyncReader makes it easier to read a given number of bytes into
+ * a target buffer asynchronously. Usage is the following:
+ *
+ * 1/ setup the reader with asyncReader_init(ar, buffer, buffsize,io);
+ * 2/ call asyncReader_read(ar, io), where 'io' is a LoopIo whenever
+ * you can receive data, i.e. just after the init() or in your
+ * own callback.
+ */
+typedef struct {
+ uint8_t* buffer;
+ size_t buffsize;
+ size_t pos;
+} AsyncReader;
+
+/* Setup an ASyncReader, by giving the address of the read buffer,
+ * and the number of bytes we want to read.
+ *
+ * This also calls loopIo_wantRead(io) for you.
+ */
+void asyncReader_init(AsyncReader* ar,
+ void* buffer,
+ size_t buffsize,
+ LoopIo* io);
+
+/* Try to read data from 'io' and return the state of the read operation.
+ *
+ * Returns:
+ * ASYNC_COMPLETE: If the read operation was complete. This will also
+ * call loopIo_dontWantRead(io) for you.
+ *
+ * ASYNC_ERROR: If an error occured (see errno). The error will be
+ * ECONNRESET in case of disconnection.
+ *
+ * ASYNC_NEED_MORE: If there was not enough incoming data to complete
+ * the read (or if 'events' doesn't contain LOOP_IO_READ).
+ */
+AsyncStatus asyncReader_read(AsyncReader* ar,
+ LoopIo* io);
+
+/* An AsyncWriter is the counterpart of an AsyncReader, but for writing
+ * data to a file descriptor asynchronously.
+ */
+typedef struct {
+ const uint8_t* buffer;
+ size_t buffsize;
+ size_t pos;
+} AsyncWriter;
+
+/* Setup an ASyncReader, by giving the address of the read buffer,
+ * and the number of bytes we want to read.
+ *
+ * This also calls loopIo_wantWrite(io) for you.
+ */
+void asyncWriter_init(AsyncWriter* aw,
+ const void* buffer,
+ size_t buffsize,
+ LoopIo* io);
+
+/* Try to write data to 'io' and return the state of the write operation.
+ *
+ * Returns:
+ * ASYNC_COMPLETE: If the write operation was complete. This will also
+ * call loopIo_dontWantWrite(io) for you.
+ *
+ * ASYNC_ERROR: If an error occured (see errno). The error will be
+ * ECONNRESET in case of disconnection.
+ *
+ * ASYNC_NEED_MORE: If not all bytes could be sent yet (or if 'events'
+ * doesn't contain LOOP_IO_READ).
+ */
+AsyncStatus asyncWriter_write(AsyncWriter* aw,
+ LoopIo* io);
+
+
+/* An AsyncLineReader allows you to read one line of text asynchronously.
+ * The biggest difference with AsyncReader is that you don't know the line
+ * size in advance, so the object will read data byte-by-byte until it
+ * encounters a '\n'.
+ */
+typedef struct {
+ uint8_t* buffer;
+ size_t buffsize;
+ size_t pos;
+} AsyncLineReader;
+
+/* Setup an AsyncLineReader to read at most 'buffsize' characters (bytes)
+ * into 'buffer'. The reader will stop when it finds a '\n' which will be
+ * part of the buffer by default.
+ *
+ * NOTE: buffsize must be > 0. If not, asyncLineReader_getLine will return
+ * ASYNC_ERROR with errno == ENOMEM.
+ *
+ * buffsize must also sufficiently big to hold the final '\n'.
+ *
+ * Also calls loopIo_wantRead(io) for you.
+ */
+void asyncLineReader_init(AsyncLineReader* alr,
+ void* buffer,
+ size_t buffsize,
+ LoopIo* io);
+
+/* Try to read line characters from 'io'.
+ * Returns:
+ * ASYNC_COMPLETE: An end-of-line was detected, call asyncLineReader_getLine
+ * to extract the line content.
+ *
+ * ASYNC_ERROR: An error occured. Note that in case of disconnection,
+ * errno will be set to ECONNRESET, but you should be able
+ * to call asyncLineReader_getLine to read the partial line
+ * that was read.
+ *
+ * In case of overflow, errno will be set to ENOMEM.
+ *
+ * ASYNC_NEED_MORE: If there was not enough incoming data (or events
+ * does not contain LOOP_IO_READ).
+ */
+AsyncStatus asyncLineReader_read(AsyncLineReader* alr,
+ LoopIo* io);
+
+/* Return a pointer to the NON-ZERO-TERMINATED line characters, if any.
+ * If 'pLength" is not NULL, the function sets '*pLength' to the length
+ * in bytes of the line.
+ *
+ * Returns:
+ * NULL if 'buffsize' was initially 0, otherwise, a pointer to 'buffer'
+ * as passed in asyncLineReader_setup().
+ *
+ * NOTE: The data is *not* zero terminated, but its last character
+ * should be '\n' unless an error occured.
+ */
+const char* asyncLineReader_getLineRaw(AsyncLineReader* alr, int *pLength);
+
+/* Return a pointer to the ZERO-TERMINATED line, with final '\n' or '\r\n'
+ * stripped. This will be NULL in case of error though.
+ */
+const char* asyncLineReader_getLine(AsyncLineReader* alr);
+
+/* Asynchronous connection to a socket
+ */
+typedef struct {
+ int error;
+ int state;
+} AsyncConnector;
+
+AsyncStatus
+asyncConnector_init(AsyncConnector* ac,
+ const SockAddress* address,
+ LoopIo* io);
+
+AsyncStatus
+asyncConnector_run(AsyncConnector* ac, LoopIo* io);
+
+#endif /* ANDROID_ASYNC_UTILS_H */