mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: jak@rudolph.ccur.com (Joe Korty)
To: wrona@mat.uni.torun.pl, golbi@mat.uni.torun.pl
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH resend] to mqueues-4.00, dynamic shared library support
Date: Thu, 20 Nov 2003 09:36:38 -0500 (EST)	[thread overview]
Message-ID: <200311201436.OAA05368@rudolph.ccur.com> (raw)

[ resend as the previous didn't appear on the list ]

Hi Michal & Krzyztof,

Patches the message queue library source file so that:

  o it can be built as a dynamic shared library.
  o apps can link against the pthreads version without -lpthread
    | In that case they get a non-pthread subset out of -lmqueue.
  o fixed warnings using -W options appropriate for library builds.

The compile-time error checks used for the warning fixups:

    -W -Wall -Wshadow -Wcast-align -Wredundant-decls \
    -Wbad-function-cast -Wcast-qual -Wwrite-strings \
    -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes

This patch applies against mqueues-4.00.  Tested against i386 and
against Opteron in both native and ia32 modes.

Regards,
Joe



diff -ura 4.00/library/src/mqueue.c new/library/src/mqueue.c
--- 4.00/library/src/mqueue.c	2003-11-08 09:20:56.000000000 -0500
+++ new/library/src/mqueue.c	2003-11-19 17:52:53.000000000 -0500
@@ -32,10 +32,7 @@
 #include "../include/mqueue.h"
 #include "config.h"
 
-#ifdef SIGEVTHREAD_SUPPORT
-#include <pthread.h>
-#endif
-
+#ifndef __NR_mq_open
 #define __NR_mq_open		274
 #define __NR_mq_unlink		(__NR_mq_open+1)
 #define __NR_mq_timedsend	(__NR_mq_open+2)
@@ -43,32 +40,39 @@
 #define __NR_mq_notify		(__NR_mq_open+4)
 #define __NR_mq_getattr		(__NR_mq_open+5)
 #define __NR_mq_setattr		(__NR_mq_open+6)
-
-#define ERRNO_OK_SIGNAL		0
-#define ERRNO_OK_THREAD		1
-#define ERRNO_REMOVE_THREAD	2
+#endif
 
 #ifdef SIGEVTHREAD_SUPPORT
+#include <pthread.h>
+
+/*
+ * Force any references in this file to the following externs to
+ * define to NULL if global definitions cannot be found at link
+ * edit time.
+ */
+#pragma weak pthread_create
+#pragma weak pthread_sigmask
+#pragma weak pthread_barrier_init
+#pragma weak pthread_barrier_wait
+#pragma weak pthread_attr_init
+#pragma weak pthread_attr_setdetachstate
+
 struct thread_communication_data
 {
-	struct sigevent notification;	/* first field must be copied as it can */
-	mqd_t mqdes;			/* be used after mq_notify exits        */
-	int *result;			/* and it can use its internal data     */
+	struct sigevent notification;	/* must be a copy of, not a ptr to */
+	mqd_t mqdes;
+	int *result;
 	pthread_barrier_t *barrier;
 };
-#endif
 
+#endif /* SIGEVTHREAD_SUPPORT */
 
-_syscall5(int, mq_timedsend, mqd_t, mqdes, const char*, msg_ptr, 
-	size_t, msg_len, unsigned int, msg_prio, const struct timespec*, abs_timeout);
-_syscall5(ssize_t, mq_timedreceive, mqd_t, mqdes, char*, msg_ptr, 
-	size_t, msg_len, unsigned int*, msg_prio, const struct timespec*, abs_timeout);
-_syscall2(int, mq_getattr, mqd_t, mqdes, struct mq_attr*, mqstat);
-_syscall3(int, mq_setattr, mqd_t, mqdes, const struct mq_attr*, mqstat,
-	struct mq_attr*, omqstat);
+#define ERRNO_OK_SIGNAL		0
+#define ERRNO_OK_THREAD		1
+#define ERRNO_REMOVE_THREAD	2
 
 /* check if name is a valid path */
-inline int is_valid_path(const char *name)
+static inline int is_valid_path(const char *name)
 {
 	int len;
 	
@@ -83,7 +87,7 @@
 		goto err_einval;
 		
 	return 0;
-	
+
 err_einval:
 	errno = EINVAL;
 	return -1;
@@ -92,12 +96,63 @@
 	return -1;
 }
 
-mqd_t mq_open(const char *name, int oflag, /* mode_t mode,
-	    struct mq_attr *attr */ ...)
+/*
+ * kernel interfaces.  We use glibc's syscall(3) instead of the macros
+ * _syscall1, _syscall2, etc, as the macros generate compilation errors
+ * when mqueue.c is built as a dynamic shared library.
+ */
+static inline mqd_t __mq_open(const char  *name,
+				int oflag, mode_t mode, struct mq_attr* attr)
+{
+	return syscall(__NR_mq_open, name, oflag, mode, attr);
+}
+
+static inline int __mq_unlink(const char *name)
+{
+	return syscall(__NR_mq_unlink, name);
+}
+
+static inline int __mq_notify(mqd_t mqdes, const struct sigevent *notification)
+{
+	return syscall(__NR_mq_notify, mqdes, notification);
+}
+
+static inline int __mq_getattr(mqd_t mqdes, struct mq_attr *mqstat)
 {
-unsigned long 	mode;
-struct mq_attr 	*attr;
-va_list 	ap;
+	return syscall(__NR_mq_getattr, mqdes, mqstat);
+}
+
+static inline int __mq_setattr( mqd_t mqdes, const struct mq_attr *mqstat,
+				struct mq_attr *omqstat)
+{
+	return syscall(__NR_mq_setattr,  mqdes, mqstat, omqstat);
+}
+
+static inline int __mq_timedsend(mqd_t mqdes, const char *msg_ptr,
+				size_t msg_len, unsigned int msg_prio,
+				const struct timespec *abs_timeout)
+{
+	return syscall(__NR_mq_timedsend, mqdes, msg_ptr, msg_len,
+		msg_prio, abs_timeout);
+}
+
+static inline ssize_t __mq_timedreceive(mqd_t mqdes, char *msg_ptr,
+				size_t msg_len, unsigned int *msg_prio,
+				const struct timespec *abs_timeout)
+{
+	return syscall(__NR_mq_timedreceive, mqdes, msg_ptr, msg_len,
+		msg_prio, abs_timeout);
+}
+
+/*
+ * application-visible wrappers around the kernel interfaces
+ */
+
+mqd_t mq_open(const char *name, int oflag, ...)
+{
+	unsigned long 	mode;
+	struct mq_attr 	*attr;
+	va_list 	ap;
 
 	va_start(ap, oflag);
 	mode = va_arg(ap, unsigned long);
@@ -107,10 +162,8 @@
 	if (is_valid_path(name) < 0)
 		return (mqd_t)-1;
 
-	static inline _syscall4(mqd_t, mq_open, const char *, name, int, oflag, mode_t, mode, struct mq_attr*, attr);
-    
 	/* omit leading slash */
-	return mq_open(name + 1, oflag, mode, attr);
+	return __mq_open(name + 1, oflag, mode, attr);
 }
 
 int mq_close(mqd_t mqdes)
@@ -123,51 +176,77 @@
 	if (is_valid_path(name) < 0)
 		return -1;
 	
-	static inline _syscall1(int, mq_unlink, const char*, name);
-       
-	return mq_unlink(name+1);
+	return __mq_unlink(name+1);
 }
 
-int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio)
+int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
+					unsigned int msg_prio)
 {
-	return mq_timedsend(mqdes, msg_ptr, msg_len, msg_prio, NULL);
+	return __mq_timedsend(mqdes, msg_ptr, msg_len, msg_prio, NULL);
 }
 
-ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio)
+ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len,
+					unsigned int *msg_prio)
 {
-	return mq_timedreceive(mqdes, msg_ptr, msg_len, msg_prio, NULL);
+	return __mq_timedreceive(mqdes, msg_ptr, msg_len, msg_prio, NULL);
+}
+
+int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
+					unsigned int msg_prio,
+					const struct timespec *abs_timeout)
+{
+	return __mq_timedsend(mqdes, msg_ptr, msg_len, msg_prio, abs_timeout);
+}
+
+ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len,
+					unsigned int *msg_prio,
+					const struct timespec *abs_timeout)
+{
+	return __mq_timedreceive(mqdes, msg_ptr, msg_len, msg_prio,
+		abs_timeout);
+}
+
+int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat)
+{
+	return __mq_getattr(mqdes, mqstat);
+}
+
+int mq_setattr( mqd_t mqdes, const struct mq_attr *mqstat,
+					struct mq_attr *omqstat)
+{
+	return __mq_setattr(mqdes, mqstat, omqstat);
 }
 
 #ifdef SIGEVTHREAD_SUPPORT
 static void *notification_handler(void * raw_arg)
 {
-	struct thread_communication_data arg = *(struct thread_communication_data *)raw_arg;
+	struct thread_communication_data arg =
+		*(struct thread_communication_data *)raw_arg;
 	siginfo_t info;
-	sigset_t sigset;
+	sigset_t signalset;
 	
 	arg.notification.sigev_signo = SIGUSR1;
 	
-	sigfillset(&sigset);
-	pthread_sigmask(SIG_BLOCK, &sigset, NULL);
+	sigfillset(&signalset);
+	pthread_sigmask(SIG_BLOCK, &signalset, NULL);
 	
 	/* set up kernel notification */
-	static inline _syscall2(int, mq_notify, mqd_t, _mqdes, const struct sigevent*, notification);
 	if (mq_notify(arg.mqdes, &(arg.notification))) {
 		*(arg.result) = errno;
 		pthread_barrier_wait(arg.barrier);
-		return;
+		return NULL;
 	}
 
 	/* allow parent to continue */
 	*(arg.result) = 0;
 	pthread_barrier_wait(arg.barrier);
 
-	sigemptyset(&sigset);
-	sigaddset(&sigset, arg.notification.sigev_signo);
+	sigemptyset(&signalset);
+	sigaddset(&signalset, arg.notification.sigev_signo);
 
 	/* wait for kernel signal */
 	do {
-		sigwaitinfo(&sigset, &info);
+		sigwaitinfo(&signalset, &info);
 		/* if si_errno == ERRNO_OK_SIGNAL then this signal was sent 
 		 * from kernel to whole process as an effect of SIGEV_SIGNAL 
 		 * notification
@@ -180,19 +259,20 @@
 	
 	if (info.si_errno == ERRNO_OK_THREAD)
 		(arg.notification.sigev_notify_function)(info._sifields._rt.si_sigval);
+	return NULL;
 }
 #endif
 
 int mq_notify(mqd_t mqdes, const struct sigevent *notification)
 {
-	struct sigevent n, *ptr;
+	struct sigevent n;
+	const struct sigevent *ptr;
 #ifdef SIGEVTHREAD_SUPPORT
 	pthread_t handler_thread;
 	pthread_attr_t thread_attr;
 	pthread_barrier_t barrier;
 	struct thread_communication_data thread_data;
 #endif
-	int result;
 
 	ptr = &n;
 
@@ -200,15 +280,21 @@
 		n.sigev_notify = SIGEV_NONE;
 		n.sigev_notify_attributes = NULL;
 	} else
-		ptr = (struct sigevent *) notification;
+		ptr = (const struct sigevent *) notification;
 
 	if (ptr->sigev_notify == SIGEV_THREAD) {
 #ifdef SIGEVTHREAD_SUPPORT
+		int result;
+		if (&pthread_create == NULL) {
+			errno = ENOSYS;
+			return -1;
+		}
 		pthread_barrier_init(&barrier, NULL, 2);
 
 		if (ptr->sigev_notify_attributes == NULL) {
 			pthread_attr_init(&thread_attr);
-			pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
+			pthread_attr_setdetachstate(&thread_attr,
+						PTHREAD_CREATE_DETACHED);
 			n.sigev_notify_attributes = &thread_attr;
 		}
 
@@ -217,8 +303,9 @@
 		thread_data.mqdes = mqdes;
 		thread_data.result = &result;
 
-		if (pthread_create(&handler_thread, ptr->sigev_notify_attributes, 
-				   notification_handler, &thread_data)) {
+		if (pthread_create(&handler_thread,
+					ptr->sigev_notify_attributes, 
+					notification_handler, &thread_data)) {
 			errno = EAGAIN;
 			return -1;
 		}
@@ -228,13 +315,11 @@
 			return -1;
 		}
 #else
-		fprintf(stderr, "SIGEV_THREAD not supported!\n");
 		errno = ENOSYS;
 		return -1;
 #endif		
 	} else {
-		static inline _syscall2(int, mq_notify, mqd_t, mqdes, const struct sigevent*, notification);
-		return mq_notify(mqdes, ptr);
+		return __mq_notify(mqdes, ptr);
 	}
 
 	return 0;

                 reply	other threads:[~2003-11-20 14:37 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200311201436.OAA05368@rudolph.ccur.com \
    --to=jak@rudolph.ccur.com \
    --cc=golbi@mat.uni.torun.pl \
    --cc=joe.korty@ccur.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=wrona@mat.uni.torun.pl \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®