Merge branch 'ipc'
authorAndre <maan@p133.(none)>
Tue, 21 Feb 2006 08:20:30 +0000 (09:20 +0100)
committerAndre <maan@p133.(none)>
Tue, 21 Feb 2006 08:20:30 +0000 (09:20 +0100)
Conflicts:

configure.ac
error.h

Fix these conflicts.

configure.ac
error.h
ipc.c [new file with mode: 0644]
ipc.h [new file with mode: 0644]

index 4f75f3a..0e93aa2 100644 (file)
@@ -73,7 +73,7 @@ audiod_ldflags=""
 
 server_cmdline_objs="server.cmdline"
 server_errlist_objs="server mp3 afs command net string signal random_dbtool time daemon stat
-       crypt http_send db close_on_fork plm_dbtool"
+       crypt http_send db close_on_fork plm_dbtool ipc"
 server_ldflags=""
 
 ########################################################################### ssl
diff --git a/error.h b/error.h
index a3755ce..0c4a05f 100644 (file)
--- a/error.h
+++ b/error.h
@@ -24,7 +24,7 @@ enum para_subsystem {SS_RECV,
        SS_STRING, SS_DAEMON, SS_STAT, SS_TIME, SS_GRAB_CLIENT, SS_HTTP_RECV,
        SS_RECV_COMMON, SS_FILTER_CHAIN, SS_WAV, SS_COMPRESS, SS_OGGDEC, SS_FILTER,
        SS_COMMAND, SS_RANDOM_DBTOOL, SS_PLM_DBTOOL, SS_CRYPT, SS_HTTP_SEND, SS_ORTP_SEND, SS_DB, SS_OGG,
-       SS_MP3, SS_MP3DEC, SS_SERVER, SS_AFS, SS_MYSQL, SS_RINGBUFFER};
+       SS_MP3, SS_MP3DEC, SS_SERVER, SS_AFS, SS_MYSQL, SS_IPC, SS_RINGBUFFER};
 #define NUM_SS (SS_RINGBUFFER + 1)
 extern const char **para_errlist[];
 /** \endcond */
@@ -227,6 +227,14 @@ extern const char **para_errlist[];
 #define PLM_DBTOOL_ERRORS \
        PARA_ERROR(LOAD_PLAYLIST, "failed to load playlist"), \
 
+
+#define IPC_ERRORS \
+       PARA_ERROR(SEM_GET, "failed to create semaphore"), \
+       PARA_ERROR(SEM_REMOVE, "can not remove semaphore"), \
+       PARA_ERROR(SHM_GET, "failed to allocate shared memory area"), \
+       PARA_ERROR(SHM_DESTROY, "failed to destroy shared memory area"), \
+       PARA_ERROR(SHM_DETACH, "can not detach shared memory area"), \
+
 /* these do not need error handling (yet) */
 #define SERVER_ERRORS
 #define WAV_ERRORS
@@ -340,6 +348,7 @@ SS_ENUM(HTTP_SEND);
 SS_ENUM(ORTP_SEND);
 SS_ENUM(DB);
 SS_ENUM(MYSQL);
+SS_ENUM(IPC);
 SS_ENUM(RINGBUFFER);
 /** \endcond */
 #undef PARA_ERROR
diff --git a/ipc.c b/ipc.c
new file mode 100644 (file)
index 0000000..9ae2b3a
--- /dev/null
+++ b/ipc.c
@@ -0,0 +1,105 @@
+#include "para.h"
+#include "error.h"
+#include "ipc.h"
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+
+int mutex_new(void)
+{
+       int ret = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666);
+       return ret < 0?  -E_SEM_GET : ret;
+}
+
+int mutex_remove(int id)
+{
+       int ret = semctl(id, 0, IPC_RMID);
+       return ret < 0? -E_SEM_REMOVE : 1;
+}
+
+static void para_semop(int id, struct sembuf *sops, int num)
+{
+       if (semop(id, sops, num) >= 0)
+               return;
+       PARA_WARNING_LOG("semop failed (%s), retrying\n", strerror(errno));
+       while (semop(id, sops, num) < 0)
+               ; /* nothing */
+}
+
+/**
+ * lock the given mutex
+ *
+ * \sa semop(2), struct misc_meta_data
+ */
+void mutex_lock(int id)
+{
+       struct sembuf sops[2] = {
+               {
+                       .sem_num = 0,
+                       .sem_op = 0,
+                       .sem_flg = SEM_UNDO
+               },
+               {
+                       .sem_num = 0,
+                       .sem_op = 1,
+                       .sem_flg = SEM_UNDO
+               }
+       };
+       para_semop(id, sops, 2);
+}
+
+/**
+ * unlock a mutex
+ *
+ * \sa semop(2), struct misc_meta_data
+ */
+void mutex_unlock(int id)
+{
+       struct sembuf sops[1] = {
+               {
+                       .sem_num = 0,
+                       .sem_op = -1,
+                       .sem_flg = SEM_UNDO
+               },
+       };
+       para_semop(id, sops, 1);
+}
+
+/**
+ * create a new shared memory area of given size
+ * 
+ * \sa shmget(2)
+ */
+int shm_new(size_t size)
+{
+       int ret = shmget(IPC_PRIVATE, size, IPC_CREAT | IPC_EXCL | 0600);
+       return ret < 0 ? -E_SHM_GET : ret;
+}
+
+/**
+ * destroy the given shared memory area
+ * \sa shmctl(2)
+ **/
+int shm_destroy(int id)
+{
+       struct shmid_ds shm_desc;
+       int ret = shmctl(id, IPC_RMID, &shm_desc);
+       return ret < 0? -E_SHM_DESTROY : ret;
+}
+
+/**
+ * attach a shared memory area
+ *
+ * \sa semop(2)
+ */
+void *shm_attach(int id, enum shm_attach_mode mode)
+{
+       if (mode == ATTACH_RW)
+               return shmat(id, NULL, 0);
+       return shmat(id, NULL, SHM_RDONLY);
+}
+int shm_detach(void *addr)
+{
+       int ret = shmdt(addr);
+       return ret < 0? -E_SHM_DETACH : 1;
+}
diff --git a/ipc.h b/ipc.h
new file mode 100644 (file)
index 0000000..25c56d2
--- /dev/null
+++ b/ipc.h
@@ -0,0 +1,7 @@
+/** \file ipc.h inter process communication and shared memory routines */
+
+enum shm_attach_mode {ATTACH_RO, ATTACH_RW};
+
+int mutex_new(void);
+void mutex_lock(int id);
+void mutex_unlock(int id);