aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2015-08-25 07:16:48 +0200
committerMattias Andrée <maandree@operamail.com>2015-08-25 07:16:48 +0200
commita355ea128a6d2fbdbf3c01dade25ce0be4f364ac (patch)
treea89ce9c47445df5625d2009af0334047b2328d53
parentsed is a buil dep (diff)
downloadmds-a355ea128a6d2fbdbf3c01dade25ce0be4f364ac.tar.gz
mds-a355ea128a6d2fbdbf3c01dade25ce0be4f364ac.tar.bz2
mds-a355ea128a6d2fbdbf3c01dade25ce0be4f364ac.tar.xz
libmds_connection: locking
Signed-off-by: Mattias Andrée <maandree@operamail.com>
-rw-r--r--src/libmdsclient/comm.c24
-rw-r--r--src/libmdsclient/comm.h73
2 files changed, 95 insertions, 2 deletions
diff --git a/src/libmdsclient/comm.c b/src/libmdsclient/comm.c
index c9cdcde..1084e8b 100644
--- a/src/libmdsclient/comm.c
+++ b/src/libmdsclient/comm.c
@@ -37,7 +37,8 @@ void libmds_connection_initialise(libmds_connection_t* restrict this)
/**
* Allocate and initialise a connection descriptor
*
- * @return The connection descriptor, `NULL` on error
+ * @return The connection descriptor, `NULL` on error,
+ * `errno` will have been set accordingly on error
*
* @throws ENOMEM Out of memory, Possibly, the process hit the RLIMIT_AS or
* RLIMIT_DATA limit described in getrlimit(2).
@@ -78,3 +79,24 @@ void libmds_connection_free(libmds_connection_t* restrict this)
free(this);
}
+
+int libmds_connection_send(libmds_connection_t* restrict this, const char* message, size_t length)
+{
+ int r, saved_errno;
+
+ if (libmds_connection_lock(this))
+ return -1;
+
+ r = libmds_connection_send_unlocked(this, message, length);
+
+ saved_errno = errno;
+ libmds_connection_unlock(this);
+ return errno = saved_errno, r;
+}
+
+
+int libmds_connection_send_unlocked(libmds_connection_t* restrict this, const char* message, size_t length)
+{
+ /* TODO */
+}
+
diff --git a/src/libmdsclient/comm.h b/src/libmdsclient/comm.h
index 9cc3b74..8f3f0d9 100644
--- a/src/libmdsclient/comm.h
+++ b/src/libmdsclient/comm.h
@@ -21,6 +21,9 @@
#include <stdint.h>
#include <stddef.h>
+#include <pthread.h>
+#include <time.h>
+#include <errno.h>
@@ -46,6 +49,12 @@ typedef struct libmds_connection
*/
char* client_id;
+ /**
+ * Mutex used to hinder concurrent modification
+ * and concurrent message passing
+ */
+ pthread_mutex_t mutex;
+
} libmds_connection_t;
@@ -60,7 +69,8 @@ void libmds_connection_initialise(libmds_connection_t* restrict this);
/**
* Allocate and initialise a connection descriptor
*
- * @return The connection descriptor, `NULL` on error
+ * @return The connection descriptor, `NULL` on error,
+ * `errno` will have been set accordingly on error
*
* @throws ENOMEM Out of memory, Possibly, the process hit the RLIMIT_AS or
* RLIMIT_DATA limit described in getrlimit(2).
@@ -82,6 +92,67 @@ void libmds_connection_destroy(libmds_connection_t* restrict this);
*/
void libmds_connection_free(libmds_connection_t* restrict this);
+/**
+ * TODO doc
+ */
+__attribute__((nonnull))
+int libmds_connection_send(libmds_connection_t* restrict this, const char* message, size_t length);
+
+/**
+ * TODO doc
+ */
+__attribute__((nonnull))
+int libmds_connection_send_unlocked(libmds_connection_t* restrict this, const char* message, size_t length);
+
+/**
+ * Lock the connection descriptor for being modified,
+ * or used to send data to the display, by another thread
+ *
+ * @param this:libmds_connection_t* The connection descriptor
+ * @return :int Zero on success, -1 on error, `errno`
+ * will have been set accordingly on error
+ * @throws See pthread_mutex_lock(3)
+ */
+#define libmds_connection_lock(this) \
+ (errno = pthread_mutex_lock(&((this)->mutex)), (errno ? 0 : -1))
+
+/**
+ * Lock the connection descriptor for being modified,
+ * or used to send data to the display, by another thread
+ *
+ * @param this:libmds_connection_t* The connection descriptor
+ * @return :int Zero on success, -1 on error, `errno`
+ * will have been set accordingly on error
+ * @throws See pthread_mutex_trylock(3)
+ */
+#define libmds_connection_trylock(this) \
+ (errno = pthread_mutex_trylock(&((this)->mutex)), (errno ? 0 : -1))
+
+/**
+ * Lock the connection descriptor for being modified,
+ * or used to send data to the display, by another thread
+ *
+ * @param this:libmds_connection_t* The connection descriptor
+ * @param deadline:const struct timespec *restrict The CLOCK_REALTIME time when the function shall fail
+ * @return :int Zero on success, -1 on error, `errno`
+ * will have been set accordingly on error
+ * @throws See pthread_mutex_timedlock(3)
+ */
+#define libmds_connection_timedlock(this, deadline) \
+ (errno = pthread_mutex_timedlock(&((this)->mutex), deadline), (errno ? 0 : -1))
+
+/**
+ * Undo the action of `libmds_connection_lock`, `libmds_connection_trylock`
+ * or `libmds_connection_timedlock`
+ *
+ * @param this:libmds_connection_t* The connection descriptor
+ * @return :int Zero on success, -1 on error, `errno`
+ * will have been set accordingly on error
+ * @throws See pthread_mutex_unlock(3)
+ */
+#define libmds_connection_unlock(this)
+ (errno = pthread_mutex_unlock(&((this)->mutex)), (errno ? 0 : -1))
+
#endif