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 sa...@apache.org on 2006/02/09 05:53:12 UTC

svn commit: r376184 - in /webservices/axis2/trunk/c: include/axis2_thread.h modules/core/transport/http/receiver/http_svr_thread.c modules/platforms/unix/Makefile.am modules/platforms/unix/axis2_thread_unix.h modules/platforms/unix/thread_unix.c

Author: sahan
Date: Wed Feb  8 20:53:10 2006
New Revision: 376184

URL: http://svn.apache.org/viewcvs?rev=376184&view=rev
Log:
Initial files for thread support.(platform independent thread abstraction and the unix (linux) implementation of the abstraction)

Added:
    webservices/axis2/trunk/c/include/axis2_thread.h
    webservices/axis2/trunk/c/modules/platforms/unix/axis2_thread_unix.h
    webservices/axis2/trunk/c/modules/platforms/unix/thread_unix.c
Modified:
    webservices/axis2/trunk/c/modules/core/transport/http/receiver/http_svr_thread.c
    webservices/axis2/trunk/c/modules/platforms/unix/Makefile.am

Added: webservices/axis2/trunk/c/include/axis2_thread.h
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/c/include/axis2_thread.h?rev=376184&view=auto
==============================================================================
--- webservices/axis2/trunk/c/include/axis2_thread.h (added)
+++ webservices/axis2/trunk/c/include/axis2_thread.h Wed Feb  8 20:53:10 2006
@@ -0,0 +1,164 @@
+/*
+ * 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_H
+#define AXIS2_THREAD_H
+
+
+/**
+  * @file axis2_thread.h
+  * @brief axis2 thread api
+  */
+
+#include <axis2.h>
+#include <axis2_defines.h>
+#include <axis2_allocator.h>
+
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @ingroup axis2_utils
+ * @{
+ */
+	
+/**
+ * Thread callbacks from axis2 functions must be declared with AXIS2_THREAD_FUNC
+ * so that they follow the platform's calling convention.
+ */
+#define AXIS2_THREAD_FUNC
+	
+/** Thread structure. */
+typedef struct axis2_thread_t           axis2_thread_t;
+
+/** Thread attributes structure. */
+typedef struct axis2_threadattr_t       axis2_threadattr_t;
+
+/** Control variable for one-time atomic variables.  */
+typedef struct axis2_thread_once_t      axis2_thread_once_t;
+
+/**
+ * The prototype for any AXIS2 thread worker functions.
+ */
+typedef void *(AXIS2_THREAD_FUNC *axis2_thread_start_t)(axis2_thread_t*, void*);
+
+/** Thread private address space. */
+typedef struct axis2_threadkey_t        axis2_threadkey_t;
+
+/* Thread Function definitions */
+
+/**
+ * Create and initialize a new threadattr variable
+ * @param cont The pool to use
+ * @return Newly created thread attribute
+ */
+AXIS2_DECLARE(axis2_threadattr_t*) axis2_threadattr_create(axis2_env_t **env);
+
+/**
+ * Set if newly created threads should be created in detached state.
+ * @param attr The threadattr to affect
+ * @param on Non-zero if detached threads should be created.
+ * @return The status of the operation
+ */
+AXIS2_DECLARE(axis2_status_t) axis2_threadattr_detach_set(
+						axis2_threadattr_t *attr, axis2_env_t **env, 
+						axis2_bool_t detached);
+
+/**
+ * Get the detach state for this threadattr.
+ * @param attr The threadattr to reference
+ * @return AXIS2_TRUE if threads are to be detached, or AXIS2_FALSE
+ * if threads are to be joinable.
+ */
+AXIS2_DECLARE(axis2_bool_t) axis2_threadattr_is_detach(
+						axis2_threadattr_t *attr, axis2_env_t **env);
+
+
+/**
+ * Create a new thread of execution
+ * @param attr The threadattr to use to determine how to create the thread
+ * @param func The function to start the new thread in
+ * @param data Any data to be passed to the starting function
+ * @param cont The pool to use
+ * @return The newly created thread handle.
+ */
+AXIS2_DECLARE(axis2_thread_t*) axis2_thread_create(axis2_env_t **env, 
+						axis2_threadattr_t *attr,
+                        axis2_thread_start_t func,
+                        void *data);
+
+/**
+ * stop the current thread
+ * @param thd The thread to stop
+ * @return The status of the operation
+ */
+AXIS2_DECLARE(axis2_status_t) axis2_thread_exit(axis2_thread_t *thd, 
+						axis2_env_t **env);
+
+/**
+ * block until the desired thread stops executing.
+ * @param retval The return value from the dead thread.
+ * @param thd The thread to join
+ * @return The status of the operation
+ */
+AXIS2_DECLARE(axis2_status_t) axis2_thread_join(axis2_thread_t *thd, 
+						axis2_env_t **env);
+
+/**
+ * force the current thread to yield the processor
+ */
+AXIS2_DECLARE(void) axis2_thread_yield(axis2_env_t **env);
+
+/**
+ * Initialize the control variable for axis2_thread_once.
+ * @param control The control variable to initialize
+ * @return The status of the operation
+ */
+AXIS2_DECLARE(axis2_status_t) axis2_thread_once_init(
+						axis2_thread_once_t **control, axis2_env_t **env);
+
+/**
+ * Run the specified function one time, regardless of how many threads
+ * call it.
+ * @param control The control variable.  The same variable should
+ *                be passed in each time the function is tried to be
+ *                called.  This is how the underlying functions determine
+ *                if the function has ever been called before.
+ * @param func The function to call.
+ * @return The status of the operation
+ */
+AXIS2_DECLARE(axis2_status_t) axis2_thread_once(axis2_thread_once_t *control, 
+						axis2_env_t **env, void (*func)(void));
+
+/**
+ * detach a thread
+ * @param thd The thread to detach
+ * @return The status of the operation
+ */
+AXIS2_DECLARE(axis2_status_t) axis2_thread_detach(axis2_thread_t *thd, 
+						axis2_env_t **env);
+
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif                          /* AXIS2_THREAD_H */

Modified: webservices/axis2/trunk/c/modules/core/transport/http/receiver/http_svr_thread.c
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/c/modules/core/transport/http/receiver/http_svr_thread.c?rev=376184&r1=376183&r2=376184&view=diff
==============================================================================
--- webservices/axis2/trunk/c/modules/core/transport/http/receiver/http_svr_thread.c (original)
+++ webservices/axis2/trunk/c/modules/core/transport/http/receiver/http_svr_thread.c Wed Feb  8 20:53:10 2006
@@ -172,33 +172,35 @@
 		{
 			continue;
 		}
-		AXIS2_PLATFORM_GET_TIME_IN_MILLIS(&t1);
-		svr_conn = axis2_simple_http_svr_conn_create(env, socket);
-		AXIS2_SIMPLE_HTTP_SVR_CONN_SET_RCV_TIMEOUT(svr_conn, env, 
-						axis2_http_socket_read_timeout);
-		request = AXIS2_SIMPLE_HTTP_SVR_CONN_READ_REQUEST(svr_conn, env);
-		tmp = svr_thread_impl->worker;
-		status = AXIS2_HTTP_WORKER_PROCESS_REQUEST(tmp, env, svr_conn, request);
-		AXIS2_SIMPLE_HTTP_SVR_CONN_FREE(svr_conn, env);
-		AXIS2_PLATFORM_GET_TIME_IN_MILLIS(&t2);
-		millisecs = t2.millitm - t1.millitm;
-		secs = difftime(t2.time, t1.time);
-		if(millisecs < 0)
+		/* This block goes inside thread execution */
 		{
-			millisecs += 1000;
-			secs--;
+			AXIS2_PLATFORM_GET_TIME_IN_MILLIS(&t1);
+			svr_conn = axis2_simple_http_svr_conn_create(env, socket);
+			AXIS2_SIMPLE_HTTP_SVR_CONN_SET_RCV_TIMEOUT(svr_conn, env, 
+							axis2_http_socket_read_timeout);
+			request = AXIS2_SIMPLE_HTTP_SVR_CONN_READ_REQUEST(svr_conn, env);
+			tmp = svr_thread_impl->worker;
+			status = AXIS2_HTTP_WORKER_PROCESS_REQUEST(tmp, env, svr_conn, request);
+			AXIS2_SIMPLE_HTTP_SVR_CONN_FREE(svr_conn, env);
+			AXIS2_PLATFORM_GET_TIME_IN_MILLIS(&t2);
+			millisecs = t2.millitm - t1.millitm;
+			secs = difftime(t2.time, t1.time);
+			if(millisecs < 0)
+			{
+				millisecs += 1000;
+				secs--;
+			}
+			secs += millisecs/1000.0;
+			if(status == AXIS2_SUCCESS)
+			{
+				AXIS2_LOG_INFO((*env)->log, "Request served in %.3f seconds", secs);
+			}
+			else
+			{
+				AXIS2_LOG_INFO((*env)->log, "Error occured in processing request." 
+							"(%.3f seconds)", secs);
+			}
 		}
-		secs += millisecs/1000.0;
-		if(status == AXIS2_SUCCESS)
-		{
-			AXIS2_LOG_INFO((*env)->log, "Request served in %.3f seconds", secs);
-		}
-		else
-		{
-			AXIS2_LOG_INFO((*env)->log, "Error occured in processing request." 
-						"(%.3f seconds)", secs);
-		}
-		
 	}
     return AXIS2_SUCCESS;
 }

Modified: webservices/axis2/trunk/c/modules/platforms/unix/Makefile.am
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/c/modules/platforms/unix/Makefile.am?rev=376184&r1=376183&r2=376184&view=diff
==============================================================================
--- webservices/axis2/trunk/c/modules/platforms/unix/Makefile.am (original)
+++ webservices/axis2/trunk/c/modules/platforms/unix/Makefile.am Wed Feb  8 20:53:10 2006
@@ -2,7 +2,8 @@
 lib_LTLIBRARIES = libaxis2_unix.la
 noinst_HEADERS = axis2_unix.h axis2_uuid_gen_unix.h
 AM_CPPFLAGS = $(CPPFLAGS)
-libaxis2_unix_la_SOURCES = uuid_gen_unix.c
+libaxis2_unix_la_SOURCES = uuid_gen_unix.c\
+                           thread_unix.c
 
 libaxis2_unix_la_LIBADD = 
 INCLUDES = -I$(top_builddir)/include\

Added: webservices/axis2/trunk/c/modules/platforms/unix/axis2_thread_unix.h
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/c/modules/platforms/unix/axis2_thread_unix.h?rev=376184&view=auto
==============================================================================
--- webservices/axis2/trunk/c/modules/platforms/unix/axis2_thread_unix.h (added)
+++ webservices/axis2/trunk/c/modules/platforms/unix/axis2_thread_unix.h Wed Feb  8 20:53:10 2006
@@ -0,0 +1,46 @@
+/*
+ * 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_UNIX_H
+#define AXIS2_THREAD_UNIX_H
+
+#include <axis2_thread.h>
+#include <pthread.h>
+
+#define SHELL_PATH "/bin/sh"
+
+typedef pthread_t axis2_os_thread_t; /* Native thread */
+
+struct axis2_thread_t {
+    pthread_t *td;
+    void *data;
+    axis2_thread_start_t func;
+    axis2_status_t exitval;
+};
+
+struct axis2_threadattr_t {
+    pthread_attr_t attr;
+};
+
+struct axis2_threadkey_t {
+    pthread_key_t key;
+};
+
+struct axis2_thread_once_t {
+    pthread_once_t once;
+};
+
+#endif  /* AXIS2_THREAD_UNIX_H */

Added: webservices/axis2/trunk/c/modules/platforms/unix/thread_unix.c
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/c/modules/platforms/unix/thread_unix.c?rev=376184&view=auto
==============================================================================
--- webservices/axis2/trunk/c/modules/platforms/unix/thread_unix.c (added)
+++ webservices/axis2/trunk/c/modules/platforms/unix/thread_unix.c Wed Feb  8 20:53:10 2006
@@ -0,0 +1,203 @@
+/*
+ * 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_unix.h"
+
+
+AXIS2_DECLARE(axis2_threadattr_t*)
+axis2_threadattr_create(axis2_env_t **env)
+{
+    int stat = 0;
+	axis2_threadattr_t *new = NULL;
+
+    new = AXIS2_MALLOC((*env)->allocator, sizeof(axis2_threadattr_t));
+	if(NULL == new)
+	{
+		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE)
+		return NULL;
+	}
+    stat = pthread_attr_init(&(new->attr));
+
+    if (stat != 0) 
+	{
+		AXIS2_FREE((*env)->allocator, new);
+        return NULL;
+    }
+    return new;
+}
+
+/* Destroy the threadattr object */
+AXIS2_DECLARE(axis2_status_t)
+threadattr_cleanup(void *data)
+{
+    axis2_threadattr_t *attr = data;
+    int rv;
+	
+    rv = pthread_attr_destroy(&attr->attr);
+	
+	if(0 != rv)
+	{
+		return AXIS2_FAILURE;
+	}
+    return AXIS2_SUCCESS;
+}
+
+#define DETACH_ARG(v) ((v) ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE)
+
+AXIS2_DECLARE(axis2_status_t) axis2_threadattr_detach_set(
+						axis2_threadattr_t *attr, axis2_env_t **env,
+						axis2_bool_t detached)
+{
+    if (0 == pthread_attr_setdetachstate(&attr->attr, DETACH_ARG(detached)))
+	{
+        return AXIS2_SUCCESS;
+    }
+	return AXIS2_FAILURE;
+}
+
+AXIS2_DECLARE(axis2_status_t)
+axis2_threadattr_detach_get(axis2_threadattr_t *attr, axis2_env_t **env)
+{
+    int state = 0;
+    pthread_attr_getdetachstate(&attr->attr, &state);
+    if (state == 1)
+	{
+        return AXIS2_TRUE;
+	}
+    return AXIS2_FALSE;
+}
+
+static void *dummy_worker(void *opaque)
+{
+    axis2_thread_t *thread = (axis2_thread_t*)opaque;
+    return thread->func(thread, thread->data);
+}
+
+AXIS2_DECLARE(axis2_thread_t*)
+axis2_thread_create(axis2_env_t **env, axis2_threadattr_t *attr,
+						axis2_thread_start_t func, void *data)
+{
+    axis2_status_t stat;
+    pthread_attr_t *temp = NULL;
+	axis2_thread_t *new = NULL;
+
+    new = (axis2_thread_t *)AXIS2_MALLOC((*env)->allocator, 
+						sizeof(axis2_thread_t));
+
+    if (NULL == new) 
+	{
+        AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+		return NULL;
+    }
+    new->td = (pthread_t *)AXIS2_MALLOC((*env)->allocator, sizeof(pthread_t));
+    if (NULL == new->td) 
+	{
+        AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+		return NULL;
+    }
+
+    new->data = data;
+    new->func = func;
+
+    if (NULL != attr)
+	{
+        temp = &attr->attr;
+	}
+    else
+	{
+        temp = NULL;
+	}
+
+    if ((stat = pthread_create(new->td, temp, dummy_worker, new)) == 0) 
+	{
+        return new;
+    }
+    return NULL;
+}
+
+AXIS2_DECLARE(axis2_os_thread_t)
+axis2_os_thread_current(void)
+{
+    return pthread_self();
+}
+
+AXIS2_DECLARE(int)
+axis2_os_thread_equal(axis2_os_thread_t tid1, axis2_os_thread_t tid2)
+{
+    return pthread_equal(tid1, tid2);
+}
+
+AXIS2_DECLARE(axis2_status_t)
+axis2_thread_exit(axis2_thread_t *thd, axis2_env_t **env)
+{
+    pthread_exit(NULL);
+    return AXIS2_SUCCESS;
+}
+
+AXIS2_DECLARE(axis2_status_t)
+axis2_thread_join(axis2_thread_t *thd, axis2_env_t **env)
+{
+    void *thread_stat;
+    if (0 == pthread_join(*thd->td,(void *)&thread_stat)) 
+	{
+        return AXIS2_SUCCESS;
+    }
+ 	return AXIS2_FAILURE;
+}
+
+AXIS2_DECLARE(axis2_status_t)
+axis2_thread_detach(axis2_thread_t *thd, axis2_env_t **env)
+{
+    if (0 == pthread_detach(*(thd->td)))
+	{
+        return AXIS2_SUCCESS;
+    }
+    return AXIS2_FAILURE;
+}
+
+void axis2_thread_yield(axis2_env_t **env)
+{
+	return;
+}
+
+AXIS2_DECLARE(axis2_os_thread_t)
+axis2_os_thread_get(axis2_thread_t *thd, axis2_env_t **env)
+{
+	AXIS2_PARAM_CHECK((*env)->error, thd, AXIS2_FAILURE);
+    return thd->td;
+}
+
+AXIS2_DECLARE(axis2_status_t)
+axis2_thread_once_init(axis2_thread_once_t **control, axis2_env_t **env)
+{
+    static const pthread_once_t once_init = PTHREAD_ONCE_INIT;
+    *control = AXIS2_MALLOC((*env)->allocator, sizeof(**control));
+	if(NULL == *control)
+	{
+		AXIS2_ERROR_SET((*env)->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
+		return AXIS2_FAILURE;
+	}
+    (*control)->once = once_init;
+    return AXIS2_SUCCESS;
+}
+
+AXIS2_DECLARE(axis2_status_t)
+axis2_thread_once(axis2_thread_once_t *control, axis2_env_t **env, 
+						void (*func)(void))
+{
+    return pthread_once(&control->once, func);
+}