sbsv2/raptor/util/talon/sema.c
changeset 2 39c28ec933dd
child 13 c327db0664bb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sbsv2/raptor/util/talon/sema.c	Mon May 10 19:54:49 2010 +0100
@@ -0,0 +1,137 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+
+
+#include "sema.h"
+
+// OS specific headers
+#ifdef WIN32
+#include <windows.h>
+#include <tlhelp32.h>
+#else
+#include <semaphore.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <time.h>
+#endif
+
+#include <unistd.h>
+
+
+void sema_create(sbs_semaphore *s)
+{
+#ifdef WIN32
+	s->handle = CreateSemaphore(NULL, 1, 1, s->name);
+	if (s->handle)
+		CloseHandle(s->handle);
+	else
+		error("unable to create semaphore %s", s->name);
+#else
+	s->handle = sem_open(s->name, O_CREAT | O_EXCL, 0644, 1);
+	
+  	if (s->handle == SEM_FAILED)
+	{
+		sem_close(s->handle);
+	  	error("unable to create semaphore %s", s->name);
+	}
+	sem_close(s->handle);
+#endif
+}
+
+void sema_destroy(sbs_semaphore *s)
+{
+	#ifdef WIN32
+		/* can't destroy a windows semaphore... */
+	#else
+  		if (sem_unlink(s->name) != 0)
+		  	error("unable to unlink semaphore", s->name);
+	#endif
+}
+
+
+int sema_wait(sbs_semaphore *s)
+{
+	/* try and open the semaphore now */
+        #ifdef WIN32
+		s->handle = CreateSemaphore(NULL, 1, 1, s->name);
+		if (!s->handle)
+		{
+			error("unable to open semaphore %s", s->name);
+			return -2;
+		}
+        #else
+		struct timespec tmout;
+		
+		s->handle = sem_open(s->name, 0);
+	
+	  	if (s->handle == SEM_FAILED)
+		{
+    			sem_close(s->handle);
+      			error("unable to open semaphore %s\n", s->name);
+			return -2;
+    		}
+	#endif
+    
+    /* wait for the semaphore to be free [timeout if it takes too long] */
+ 	int timedOutFlag = 0;
+	int semcount = 0;
+	#ifdef WIN32
+ 		timedOutFlag = (WaitForSingleObject(s->handle, s->timeout) != WAIT_OBJECT_0);
+	#else
+
+		sem_getvalue(s->handle, &semcount);
+      		debug("sema: count before wait: %d\n", semcount);
+      		debug("sema: timeout: %d\n", s->timeout);
+
+	        if (clock_gettime(CLOCK_REALTIME, &tmout) == -1)
+		{
+               		error("sema: clock_gettime failed - can't do timed wait");
+			return -1;
+		}
+
+		tmout.tv_sec += (s->timeout / 1000);
+		tmout.tv_nsec += (s->timeout % 1000) * 1000;
+		timedOutFlag = sem_timedwait(s->handle, &tmout); 
+		/* roughly speaking the return value indicates timeouts. It also indicated
+		 * signals.  We are glossing over this for the moment since it isn't really
+		 * interesting in this application 
+		 * */
+	#endif
+
+	return timedOutFlag;
+}
+
+
+void  sema_release(sbs_semaphore *s)
+{
+	/* release the semaphore */
+	#ifdef WIN32
+		ReleaseSemaphore(s->handle, 1, NULL);
+	#else
+	   	sem_post(s->handle);
+	#endif
+	
+	   /* clean up */
+	#ifdef WIN32
+		CloseHandle(s->handle);
+	#else
+	   	sem_close(s->handle);
+	#endif
+}