You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by da...@apache.org on 2006/02/13 03:20:57 UTC

svn commit: r377290 - in /webservices/axis2/trunk/c/modules/platforms/windows: axis2_thread_mutex_windows.h axis2_thread_windows.h thread_mutex_windows.c thread_windows.c

Author: damitha
Date: Sun Feb 12 18:20:56 2006
New Revision: 377290

URL: http://svn.apache.org/viewcvs?rev=377290&view=rev
Log:
thread and mutex implementation for win32

Added:
    webservices/axis2/trunk/c/modules/platforms/windows/axis2_thread_mutex_windows.h   (with props)
    webservices/axis2/trunk/c/modules/platforms/windows/axis2_thread_windows.h   (with props)
    webservices/axis2/trunk/c/modules/platforms/windows/thread_mutex_windows.c   (with props)
    webservices/axis2/trunk/c/modules/platforms/windows/thread_windows.c   (with props)

Added: webservices/axis2/trunk/c/modules/platforms/windows/axis2_thread_mutex_windows.h
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/c/modules/platforms/windows/axis2_thread_mutex_windows.h?rev=377290&view=auto
==============================================================================
--- webservices/axis2/trunk/c/modules/platforms/windows/axis2_thread_mutex_windows.h (added)
+++ webservices/axis2/trunk/c/modules/platforms/windows/axis2_thread_mutex_windows.h Sun Feb 12 18:20:56 2006
@@ -0,0 +1,25 @@
+#ifndef AXIS2_THREAD_MUTEX_WINDOWS_H
+#define AXIS2_THREAD_MUTEX_WINDOWS_H
+
+#include <process.h>
+
+typedef enum thread_mutex_type 
+{
+    thread_mutex_critical_section,
+    thread_mutex_unnested_event,
+    thread_mutex_nested_mutex
+} thread_mutex_type;
+
+/* handle applies only to unnested_event on all platforms 
+ * and nested_mutex on Win9x only.  Otherwise critical_section 
+ * is used for NT nexted mutexes providing optimal performance.
+ */
+struct axis2_thread_mutex_t 
+{
+    thread_mutex_type type;
+    HANDLE            handle;
+    CRITICAL_SECTION  section;
+};
+
+#endif  /* AXIS2_THREAD_MUTEX_WINDOWS_H */
+

Propchange: webservices/axis2/trunk/c/modules/platforms/windows/axis2_thread_mutex_windows.h
------------------------------------------------------------------------------
    svn:executable = *

Added: webservices/axis2/trunk/c/modules/platforms/windows/axis2_thread_windows.h
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/c/modules/platforms/windows/axis2_thread_windows.h?rev=377290&view=auto
==============================================================================
--- webservices/axis2/trunk/c/modules/platforms/windows/axis2_thread_windows.h (added)
+++ webservices/axis2/trunk/c/modules/platforms/windows/axis2_thread_windows.h Sun Feb 12 18:20:56 2006
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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 AXIS2_THREAD_WINDOWS_H
+#define AXIS2_THREAD_WINDOWS_H
+
+#include <windows.h>
+#include <process.h>
+#include <axis2_thread.h>
+
+#define SHELL_PATH "cmd.exe"
+
+typedef HANDLE axis2_os_thread_t; /* Native thread */
+/* Chosen for us by apr_initialize */
+DWORD tls_axis2_thread = 0;
+
+struct axis2_thread_t 
+{
+	HANDLE *td;
+    void *data;
+    axis2_thread_start_t func;
+};
+
+struct axis2_threadattr_t 
+{
+    int detach;
+    size_t stacksize;
+};
+
+struct axis2_threadkey_t 
+{
+	DWORD key;
+};
+
+struct axis2_thread_once_t 
+{
+	long value;
+};
+
+#endif  /* AXIS2_THREAD_WINDOWS_H */

Propchange: webservices/axis2/trunk/c/modules/platforms/windows/axis2_thread_windows.h
------------------------------------------------------------------------------
    svn:executable = *

Added: webservices/axis2/trunk/c/modules/platforms/windows/thread_mutex_windows.c
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/c/modules/platforms/windows/thread_mutex_windows.c?rev=377290&view=auto
==============================================================================
--- webservices/axis2/trunk/c/modules/platforms/windows/thread_mutex_windows.c (added)
+++ webservices/axis2/trunk/c/modules/platforms/windows/thread_mutex_windows.c Sun Feb 12 18:20:56 2006
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.
+ */
+
+
+#include <axis2_thread_mutex.h>
+#include "axis2_thread_mutex_windows.h"
+
+static axis2_status_t thread_mutex_cleanup(void *data)
+{
+    axis2_thread_mutex_t *lock = data;
+
+    if (lock->type == thread_mutex_critical_section) 
+	{
+        DeleteCriticalSection(&lock->section);
+    }
+    else 
+	{
+        if (!CloseHandle(lock->handle)) {
+            return AXIS2_FAILURE;
+        }
+    }
+    return AXIS2_SUCCESS;
+}
+
+AXIS2_DECLARE(axis2_thread_mutex_t *) axis2_thread_mutex_create(axis2_allocator_t *allocator,
+                                                  unsigned int flags)
+{
+	axis2_thread_mutex_t *mutex = NULL;
+
+    mutex = (axis2_thread_mutex_t *)AXIS2_MALLOC(allocator, sizeof(*mutex));
+
+    if (flags & AXIS2_THREAD_MUTEX_UNNESTED) 
+	{
+        /* Use an auto-reset signaled event, ready to accept one
+         * waiting thread.
+         */
+        mutex->type = thread_mutex_unnested_event;
+        mutex->handle = CreateEvent(NULL, FALSE, TRUE, NULL);
+    }
+	else
+	{
+		/*TODO:support critical_section and nested_mutex*/
+	}
+   
+    return mutex;
+}
+
+AXIS2_DECLARE(axis2_status_t) axis2_thread_mutex_lock(axis2_thread_mutex_t *mutex)
+{
+    if (mutex->type == thread_mutex_critical_section) 
+	{
+        EnterCriticalSection(&mutex->section);
+    }
+    else 
+	{
+        DWORD rv = WaitForSingleObject(mutex->handle, INFINITE);
+		if ((rv != WAIT_OBJECT_0) && (rv != WAIT_ABANDONED)) 
+		{
+			return AXIS2_FAILURE;
+            /*can be either BUSY or an os specific error*/
+		}
+    }        
+    return AXIS2_SUCCESS;
+}
+
+AXIS2_DECLARE(axis2_status_t) axis2_thread_mutex_trylock(axis2_thread_mutex_t *mutex)
+{
+	/*TODO:implement trylock for critical section*/
+    /*if (mutex->type == thread_mutex_critical_section) 
+	{
+        if (!TryEnterCriticalSection(&mutex->section)) 
+		{
+            return AXIS2_FAILURE; //return APR_EBUSY;
+        }
+    }
+    else*/ 
+	{
+        DWORD rv = WaitForSingleObject(mutex->handle, 0);
+		if ((rv != WAIT_OBJECT_0) && (rv != WAIT_ABANDONED))
+		{
+            /*can be either BUSY or an os specific error*/
+			return AXIS2_FAILURE;
+		}
+    }        
+    return AXIS2_SUCCESS;
+}
+
+AXIS2_DECLARE(axis2_status_t) axis2_thread_mutex_unlock(axis2_thread_mutex_t *mutex)
+{
+    if (mutex->type == thread_mutex_critical_section)
+	{
+        LeaveCriticalSection(&mutex->section);
+    }
+    else if (mutex->type == thread_mutex_unnested_event)
+	{
+        if (!SetEvent(mutex->handle)) 
+		{
+            /*os specific error*/
+			return AXIS2_FAILURE;
+        }
+    }
+    else if (mutex->type == thread_mutex_nested_mutex) 
+	{
+        if (!ReleaseMutex(mutex->handle)) 
+		{
+            /*os specific error*/
+			return AXIS2_FAILURE;
+        }
+    }
+    return AXIS2_SUCCESS;
+}
+
+AXIS2_DECLARE(axis2_status_t) axis2_thread_mutex_destroy(axis2_thread_mutex_t *mutex)
+{
+    return thread_mutex_cleanup((void*)mutex);
+}
\ No newline at end of file

Propchange: webservices/axis2/trunk/c/modules/platforms/windows/thread_mutex_windows.c
------------------------------------------------------------------------------
    svn:executable = *

Added: webservices/axis2/trunk/c/modules/platforms/windows/thread_windows.c
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/c/modules/platforms/windows/thread_windows.c?rev=377290&view=auto
==============================================================================
--- webservices/axis2/trunk/c/modules/platforms/windows/thread_windows.c (added)
+++ webservices/axis2/trunk/c/modules/platforms/windows/thread_windows.c Sun Feb 12 18:20:56 2006
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ *
+ * 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.
+ */
+
+#include <axis2.h>
+#include "axis2_thread_windows.h"
+
+AXIS2_DECLARE(axis2_threadattr_t*)
+axis2_threadattr_create(axis2_allocator_t *allocator)
+{
+    axis2_threadattr_t *new = NULL;
+
+    new = AXIS2_MALLOC(allocator, sizeof(axis2_threadattr_t));
+	if(NULL == new)
+	{
+		/*AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE)*/
+		return NULL;
+	}
+    new->detach = 0;
+	new->stacksize = 0;
+
+    return new;
+}
+
+/* Destroy the threadattr object */
+AXIS2_DECLARE(axis2_status_t)
+threadattr_cleanup(void *data)
+{
+    axis2_threadattr_t *attr = data;
+    /*nothing to clean up*/
+    return AXIS2_SUCCESS;
+}
+
+AXIS2_DECLARE(axis2_status_t) axis2_threadattr_detach_set(
+						axis2_threadattr_t *attr,
+						axis2_bool_t detached)
+{
+	attr->detach = detached;
+	return AXIS2_SUCCESS;
+}
+
+AXIS2_DECLARE(axis2_status_t)
+axis2_threadattr_detach_get(axis2_threadattr_t *attr, axis2_env_t **env)
+{
+	if (1 == attr->detach)
+	{
+        return AXIS2_TRUE;
+	}
+    return AXIS2_FALSE;
+}
+
+AXIS2_DECLARE(axis2_status_t) 
+axis2_threadattr_stacksize_set(axis2_threadattr_t *attr, size_t stacksize)
+{
+    attr->stacksize = stacksize;
+    return AXIS2_SUCCESS;
+}
+
+static void *dummy_worker(void *opaque)
+{
+    axis2_thread_t *thd = (axis2_thread_t *)opaque;
+    TlsSetValue(tls_axis2_thread, thd->td);
+    return thd->func(thd, thd->data);
+}
+
+AXIS2_DECLARE(axis2_thread_t*)
+axis2_thread_create(axis2_allocator_t *allocator, axis2_threadattr_t *attr,
+						axis2_thread_start_t func, void *data)
+{
+    HANDLE           handle;
+	unsigned         temp;
+    axis2_thread_t   *new = NULL;
+
+    new = (axis2_thread_t *)AXIS2_MALLOC(allocator, 
+						sizeof(axis2_thread_t));
+
+    if (NULL == new) 
+	{
+        return NULL;
+    }
+    
+	new->data = data;
+    new->func = func;
+	new->td   = NULL;
+
+	/* Use 0 for Thread Stack Size, because that will default the stack to the
+     * same size as the calling thread. 
+     */
+    if ((handle = CreateThread(NULL,
+                        attr && attr->stacksize > 0 ? attr->stacksize : 0,
+                        (unsigned int (AXIS2_THREAD_FUNC *)(void *))dummy_worker,
+                        new, 0, &temp)) == 0) 
+	{
+        return NULL;
+    }
+	
+    if (attr && attr->detach) {
+        CloseHandle(handle);
+    }
+    else
+        new->td = handle;
+
+	return new;
+}
+
+AXIS2_DECLARE(axis2_status_t)
+axis2_thread_exit(axis2_thread_t *thd)
+{
+    ExitThread(0);
+
+    return AXIS2_SUCCESS;
+}
+
+AXIS2_DECLARE(axis2_os_thread_t)
+axis2_os_thread_current(void)
+{
+    HANDLE hthread = (HANDLE)TlsGetValue(tls_axis2_thread);
+    HANDLE hproc;
+
+    if (hthread) 
+	{
+        return hthread;
+    }
+    
+    hproc = GetCurrentProcess();
+    hthread = GetCurrentThread();
+    if (!DuplicateHandle(hproc, hthread, 
+                         hproc, &hthread, 0, FALSE, 
+                         DUPLICATE_SAME_ACCESS)) {
+        return NULL;
+    }
+    TlsSetValue(tls_axis2_thread, hthread);
+    return hthread;
+}
+
+AXIS2_DECLARE(int)
+axis2_os_thread_equal(axis2_os_thread_t tid1, axis2_os_thread_t tid2)
+{
+    return (tid1 == tid2);
+}
+
+AXIS2_DECLARE(axis2_status_t)
+axis2_thread_join(axis2_thread_t *thd)
+{
+    axis2_status_t rv = AXIS2_SUCCESS,rv1;
+    
+    if (!thd->td)
+	{
+        /* Can not join on detached threads */
+        return AXIS2_FAILURE;
+    }
+    rv1 = WaitForSingleObject(thd->td, INFINITE);
+    if ( rv1 == WAIT_OBJECT_0 || rv1 == WAIT_ABANDONED) 
+	{
+        /*rv = AXIS2_INCOMPLETE;*/
+    }
+    else
+        rv = AXIS2_FAILURE;
+    CloseHandle(thd->td);
+    thd->td = NULL;
+
+    return rv;
+}
+
+AXIS2_DECLARE(axis2_status_t)
+axis2_thread_detach(axis2_thread_t *thd)
+{
+    if (thd->td && CloseHandle(thd->td)) 
+	{
+        thd->td = NULL;
+        return AXIS2_SUCCESS;
+    }
+    else 
+	{
+        return AXIS2_FAILURE;
+    }
+}
+
+AXIS2_DECLARE(axis2_os_thread_t)
+axis2_os_thread_get(axis2_thread_t *thd, axis2_env_t **env)
+{
+	return thd->td;
+}
+
+AXIS2_DECLARE(axis2_status_t)
+axis2_thread_once_init(axis2_thread_once_t **control, axis2_allocator_t *allocator)
+{
+    *control = AXIS2_MALLOC(allocator, sizeof(**control));
+	if(NULL == *control)
+	{
+		return AXIS2_FAILURE;
+	}
+    return AXIS2_SUCCESS;
+}
+
+AXIS2_DECLARE(axis2_status_t)
+axis2_thread_once(axis2_thread_once_t *control, void (*func)(void))
+{
+    if (!InterlockedExchange(&control->value, 1)) {
+        func();
+    }
+    return AXIS2_SUCCESS;
+}

Propchange: webservices/axis2/trunk/c/modules/platforms/windows/thread_windows.c
------------------------------------------------------------------------------
    svn:executable = *