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);
+}