diff options
author | gmcdonald | 2010-02-13 01:32:03 +0000 |
---|---|---|
committer | gmcdonald | 2010-02-13 01:32:03 +0000 |
commit | 0425aadc78680e53000fd0108b540d6eca048516 (patch) | |
tree | 8ec7ab8e015d454c5ec586dfc91e05a2dce1cfc0 /util/src/platforms | |
download | axis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.gz axis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.bz2 |
Moving axis svn, part of TLP move INFRA-2441
git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@909681 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'util/src/platforms')
-rw-r--r-- | util/src/platforms/unix/Makefile.am | 8 | ||||
-rw-r--r-- | util/src/platforms/unix/date_time_util_unix.c | 31 | ||||
-rw-r--r-- | util/src/platforms/unix/thread_unix.c | 362 | ||||
-rw-r--r-- | util/src/platforms/unix/uuid_gen_unix.c | 345 | ||||
-rw-r--r-- | util/src/platforms/windows/axutil_windows.c | 93 | ||||
-rw-r--r-- | util/src/platforms/windows/date_time_util_windows.c | 32 | ||||
-rw-r--r-- | util/src/platforms/windows/dir_windows.c | 272 | ||||
-rw-r--r-- | util/src/platforms/windows/getopt_windows.c | 137 | ||||
-rw-r--r-- | util/src/platforms/windows/thread_mutex_windows.c | 148 | ||||
-rw-r--r-- | util/src/platforms/windows/thread_windows.c | 326 | ||||
-rw-r--r-- | util/src/platforms/windows/uuid_gen_windows.c | 61 |
11 files changed, 1815 insertions, 0 deletions
diff --git a/util/src/platforms/unix/Makefile.am b/util/src/platforms/unix/Makefile.am new file mode 100644 index 0000000..6506a01 --- /dev/null +++ b/util/src/platforms/unix/Makefile.am @@ -0,0 +1,8 @@ +noinst_LTLIBRARIES = libaxis2_unix.la + +libaxis2_unix_la_SOURCES = uuid_gen_unix.c\ + thread_unix.c date_time_util_unix.c + +INCLUDES = -I$(top_builddir)/include \ + -I$(top_builddir)/include/platforms \ + -I$(top_builddir)/include/platforms/unix diff --git a/util/src/platforms/unix/date_time_util_unix.c b/util/src/platforms/unix/date_time_util_unix.c new file mode 100644 index 0000000..e0c4a28 --- /dev/null +++ b/util/src/platforms/unix/date_time_util_unix.c @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 <platforms/unix/axutil_date_time_util_unix.h> + +AXIS2_EXTERN int AXIS2_CALL +axis2_platform_get_milliseconds() +{ + struct timeb t_current; + int milliseconds; + + ftime(&t_current); + milliseconds = t_current.millitm; + + return milliseconds; + +} diff --git a/util/src/platforms/unix/thread_unix.c b/util/src/platforms/unix/thread_unix.c new file mode 100644 index 0000000..ccedd06 --- /dev/null +++ b/util/src/platforms/unix/thread_unix.c @@ -0,0 +1,362 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 <config.h> +#include "axutil_thread_unix.h" + +AXIS2_EXTERN axutil_threadattr_t *AXIS2_CALL +axutil_threadattr_create( + axutil_allocator_t * allocator) +{ + int stat = 0; + axutil_threadattr_t *new = NULL; + + new = AXIS2_MALLOC(allocator, sizeof(axutil_threadattr_t)); + if(!new) + { + return NULL; + } + stat = pthread_attr_init(&(new->attr)); + + if(stat != 0) + { + AXIS2_FREE(allocator, new); + return NULL; + } + return new; +} + +/* Destroy the threadattr object */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +threadattr_cleanup( + void *data) +{ + axutil_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_EXTERN axis2_status_t AXIS2_CALL +axutil_threadattr_detach_set( + axutil_threadattr_t * attr, + axis2_bool_t detached) +{ + if(0 == pthread_attr_setdetachstate(&(attr->attr), DETACH_ARG(detached))) + { + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_threadattr_detach_get( + axutil_threadattr_t * attr) +{ + int state = 0; + pthread_attr_getdetachstate(&(attr->attr), &state); + if(state == 1) + { + return AXIS2_TRUE; + } + return AXIS2_FALSE; +} + +static void * +dummy_worker( + void *opaque) +{ + axutil_thread_t *thread = (axutil_thread_t *)opaque; + return thread->func(thread, thread->data); +} + +AXIS2_EXTERN axutil_thread_t *AXIS2_CALL +axutil_thread_create( + axutil_allocator_t * allocator, + axutil_threadattr_t * attr, + axutil_thread_start_t func, + void *data) +{ + axis2_status_t stat; + pthread_attr_t *temp = NULL; + axutil_thread_t *new = NULL; + + new = (axutil_thread_t *)AXIS2_MALLOC(allocator, sizeof(axutil_thread_t)); + + if(!new) + { + return NULL; + } + new->td = (pthread_t *)AXIS2_MALLOC(allocator, sizeof(pthread_t)); + if(!new->td) + { + return NULL; + } + + new->data = data; + new->func = func; + new->try_exit = AXIS2_FALSE; + + if(attr) + { + temp = &(attr->attr); + } + else + { + temp = NULL; + } + + if((stat = pthread_create(new->td, temp, dummy_worker, new)) == 0) + { + return new; + } + return NULL; +} + +AXIS2_EXTERN axis2_os_thread_t AXIS2_CALL +axis2_os_thread_current( + void) +{ + return pthread_self(); +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_os_thread_equal( + axis2_os_thread_t tid1, + axis2_os_thread_t tid2) +{ + return pthread_equal(tid1, tid2); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_exit( + axutil_thread_t * thd, + axutil_allocator_t * allocator) +{ + axis2_bool_t same_thread = AXIS2_TRUE; + if(thd) + { + while(!thd->try_exit) + { + sleep(1); + } + + if(thd->td) + { + same_thread = pthread_equal(pthread_self(), *thd->td); + if(!same_thread) + { + pthread_kill(*(thd->td), 0); + axutil_thread_join(thd); + } + AXIS2_FREE(allocator, thd->td); + } + AXIS2_FREE(allocator, thd); + } + if(same_thread) + { + pthread_exit(NULL); + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_join( + axutil_thread_t * thd) +{ + void *thread_stat; + if(0 == pthread_join(*(thd->td), (void *)(&thread_stat))) + { + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_detach( + axutil_thread_t * thd) +{ + if(0 == pthread_detach(*(thd->td))) + { + thd->try_exit = AXIS2_TRUE; + return AXIS2_SUCCESS; + } + return AXIS2_FAILURE; +} + +void +axutil_thread_yield( + void) +{ + return; +} + +/** + * function is used to allocate a new key. This key now becomes valid for all threads in our process. + * When a key is created, the value it points to defaults to NULL. Later on each thread may change + * its copy of the value as it wishes. + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_key_create( + axutil_threadkey_t * axis2_key) +{ + int rc = -1; + pthread_key_t key = axis2_key->key; + rc = pthread_key_create(&key, NULL); + if(0 == rc) + return AXIS2_SUCCESS; + else + return AXIS2_FAILURE; +} + +/** + * This function is used to get the value of a given key + * @return void*. A key's value is simply a void pointer (void*) + */ +AXIS2_EXTERN void *AXIS2_CALL +axutil_thread_getspecific( + axutil_threadkey_t * axis2_key) +{ + void *value = NULL; + pthread_key_t key = axis2_key->key; + value = pthread_getspecific(key); + return value; +} + +/** + * This function is used to get the value of a given key + * @param keys value. A key's value is simply a void pointer (void*), so we can + * store in it anything that we want + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_setspecific( + axutil_threadkey_t * axis2_key, + void *value) +{ + int rc = -1; + pthread_key_t key = axis2_key->key; + rc = pthread_setspecific(key, value); + if(0 == rc) + return AXIS2_SUCCESS; + else + return AXIS2_FAILURE; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_thread_key_free( + axutil_threadkey_t * axis2_key) +{ + pthread_key_t key = axis2_key->key; + pthread_key_delete(key); +} + +AXIS2_EXTERN axis2_os_thread_t *AXIS2_CALL +axis2_os_thread_get( + axutil_thread_t * thd) +{ + if(!thd) + { + return NULL; + } + return thd->td; +} + +AXIS2_EXTERN axutil_thread_once_t *AXIS2_CALL +axutil_thread_once_init( + axutil_allocator_t * allocator) +{ +#if defined(AXIS2_SOLARIS) && (__GNUC__ <= 3) + static const pthread_once_t once_init = + { PTHREAD_ONCE_INIT}; +#else + static const pthread_once_t once_init = PTHREAD_ONCE_INIT; +#endif + axutil_thread_once_t *control = AXIS2_MALLOC(allocator, sizeof(axutil_thread_once_t)); + if(!control) + { + return NULL;; + } + (control)->once = once_init; + return control; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_once( + axutil_thread_once_t * control, + void + (*func)( + void)) +{ + return pthread_once(&(control->once), func); +} + +/*************************Thread locking functions*****************************/ +AXIS2_EXTERN axutil_thread_mutex_t *AXIS2_CALL +axutil_thread_mutex_create( + axutil_allocator_t * allocator, + unsigned int flags) +{ + axutil_thread_mutex_t *new_mutex = NULL; + + new_mutex = AXIS2_MALLOC(allocator, sizeof(axutil_thread_mutex_t)); + new_mutex->allocator = allocator; + + if(pthread_mutex_init(&(new_mutex->mutex), NULL) != 0) + { + AXIS2_FREE(allocator, new_mutex); + return NULL; + } + return new_mutex; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_mutex_lock( + axutil_thread_mutex_t * mutex) +{ + return pthread_mutex_lock(&(mutex->mutex)); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_mutex_unlock( + axutil_thread_mutex_t * mutex) +{ + if(pthread_mutex_unlock(&(mutex->mutex)) != 0) + { + return AXIS2_FAILURE; + } + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_mutex_destroy( + axutil_thread_mutex_t * mutex) +{ + if(0 != pthread_mutex_destroy(&(mutex->mutex))) + { + return AXIS2_FAILURE; + } + AXIS2_FREE(mutex->allocator, mutex); + return AXIS2_SUCCESS; +} diff --git a/util/src/platforms/unix/uuid_gen_unix.c b/util/src/platforms/unix/uuid_gen_unix.c new file mode 100644 index 0000000..cdc2544 --- /dev/null +++ b/util/src/platforms/unix/uuid_gen_unix.c @@ -0,0 +1,345 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 <config.h> + +#include <sys/ioctl.h> +#include <string.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <netdb.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.h> + +#ifdef HAVE_LINUX_IF_H +# include <linux/if.h> +#else +# ifdef HAVE_NET_IF_H +# include <sys/sockio.h> +# include <net/if.h> +# include <net/if_arp.h> +# endif +# ifdef HAVE_NET_IF_TYPES_H +# include <net/if_types.h> +# endif +# ifdef HAVE_NET_IF_DL_H +# include <net/if_dl.h> +# endif +#endif +#ifdef HAVE_GETIFADDRS +#include <ifaddrs.h> +#endif +#include <platforms/unix/axutil_uuid_gen_unix.h> +#include <platforms/axutil_platform_auto_sense.h> + +/* We need these static variables to track throughout the program execution */ +static axis2_bool_t axutil_uuid_gen_is_first = AXIS2_TRUE; +static struct axutil_uuid_st axutil_uuid_static; + +axutil_uuid_t *AXIS2_CALL +axutil_uuid_gen_v1() +{ + struct timeval time_now; + struct timeval tv; + unsigned long long time_val; + unsigned long long time_val2; + unsigned short int clck = 0; + axutil_uuid_t *ret_uuid = NULL; + unsigned short int time_high_version = 0; + + if(AXIS2_TRUE == axutil_uuid_gen_is_first) + { + char *mac_addr = axutil_uuid_get_mac_addr(); + memcpy(axutil_uuid_static.mac, mac_addr, 6); + axutil_uuid_static.time_seq = 0; + axutil_uuid_static.clock = 0; + free(mac_addr); + axutil_uuid_gen_is_first = AXIS2_FALSE; + } + /* + * GENERATE TIME + */ + + /* determine current system time and sequence counter */ + if(gettimeofday(&time_now, NULL) == -1) + return NULL; + + /* check whether system time changed since last retrieve */ + if(!(time_now.tv_sec == axutil_uuid_static.time_last.tv_sec && time_now.tv_usec + == axutil_uuid_static.time_last.tv_usec)) + { + /* reset time sequence counter and continue */ + axutil_uuid_static.time_seq = 0; + } + + /* until we are out of UUIDs per tick, increment + the time/tick sequence counter and continue */ + while(axutil_uuid_static.time_seq < UUIDS_PER_TICK) + { + axutil_uuid_static.time_seq++; + } + /* sleep for 1000ns (1us) */ + tv.tv_sec = 0; + tv.tv_usec = 1; + /* + The following select causes severe performance problems. + Hence commenting out. I am not sure why this is required. - Samisa. + select(0, NULL, NULL, NULL, &tv); */ + + time_val = (unsigned long long)time_now.tv_sec * 10000000ull; + time_val += (unsigned long long)time_now.tv_usec * 10ull; + + ret_uuid = malloc(sizeof(axutil_uuid_t)); + + time_val += UUID_TIMEOFFSET; + /* compensate for low resolution system clock by adding + the time/tick sequence counter */ + if(axutil_uuid_static.time_seq > 0) + time_val += (unsigned long long)axutil_uuid_static.time_seq; + + time_val2 = time_val; + ret_uuid->time_low = (unsigned long)time_val2; + time_val2 >>= 32; + ret_uuid->time_mid = (unsigned short int)time_val2; + time_val2 >>= 16; + time_high_version = (unsigned short int)time_val2; + + /* store the 60 LSB of the time in the UUID and make version 1 */ + time_high_version <<= 4; + time_high_version &= 0xFFF0; + time_high_version |= 0x0001; + ret_uuid->time_high_version = time_high_version; + + /* + * GENERATE CLOCK + */ + + /* retrieve current clock sequence */ + clck = axutil_uuid_static.clock; + + /* generate new random clock sequence (initially or if the + time has stepped backwards) or else just increase it */ + if(clck == 0 || (time_now.tv_sec < axutil_uuid_static.time_last.tv_sec || (time_now.tv_sec + == axutil_uuid_static.time_last.tv_sec && time_now.tv_usec + < axutil_uuid_static.time_last.tv_usec))) + { + srand(time_now.tv_usec); + clck = rand(); + } + else + { + clck++; + } + clck %= (2 << 14); + + /* store back new clock sequence */ + axutil_uuid_static.clock = clck; + + clck &= 0x1FFF; + clck |= 0x2000; + + /* + * FINISH + */ + /* remember current system time for next iteration */ + axutil_uuid_static.time_last.tv_sec = time_now.tv_sec; + axutil_uuid_static.time_last.tv_usec = time_now.tv_usec; + + if(!ret_uuid) + { + return NULL; + } + ret_uuid->clock_variant = clck; + memcpy(ret_uuid->mac_addr, axutil_uuid_static.mac, 6); + return ret_uuid; +} + +axis2_char_t *AXIS2_CALL +axutil_platform_uuid_gen( + char *s) +{ + axutil_uuid_t *uuid_struct = NULL; + axis2_char_t *uuid_str = NULL; + unsigned char mac[7]; + char mac_hex[13]; + + if(!s) + { + return NULL; + } + uuid_struct = axutil_uuid_gen_v1(); + if(!uuid_struct) + { + return NULL; + } + uuid_str = s; + if(!uuid_str) + { + return NULL; + } + memcpy(mac, uuid_struct->mac_addr, 6); + sprintf(mac_hex, "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + sprintf(uuid_str, "%08x-%04x-%04x-%04x-%s", uuid_struct->time_low, uuid_struct->time_mid, + uuid_struct->time_high_version, uuid_struct->clock_variant, mac_hex); + free(uuid_struct); + uuid_struct = NULL; + return uuid_str; +} + +#ifdef HAVE_LINUX_IF_H /* Linux */ + +char *AXIS2_CALL +axutil_uuid_get_mac_addr( +) +{ + struct ifreq ifr; + struct ifreq *IFR; + struct ifconf ifc; + struct sockaddr *sa; + int s = 0; + int i = 0; + char *buffer = NULL; + char buf[1024]; + int ok = AXIS2_FALSE; + + if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) + return NULL; + + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + ioctl(s, SIOCGIFCONF, &ifc); + IFR = ifc.ifc_req; + + for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; IFR++) + { + strcpy(ifr.ifr_name, IFR->ifr_name); + /*sprintf(ifr.ifr_name, "eth0"); */ + if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) + { + if (!(ifr.ifr_flags & IFF_LOOPBACK)) + { + if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0) + { + ok = AXIS2_TRUE; + break; + } + } + } + } + buffer = (char *) malloc(6 * sizeof(char)); + if (ok) + { + sa = (struct sockaddr *) &ifr.ifr_addr; + for (i = 0; i < 6; i++) + buffer[i] = (unsigned char) (sa->sa_data[i] & 0xff); + } + else + { + for (i = 0; i < 6; i++) + buffer[i] = (unsigned char) ((AXIS2_LOCAL_MAC_ADDR[i]) - '0'); + } + close(s); + return buffer; +} + +#else + +#ifdef HAVE_GETIFADDRS /* NetBSD, MacOSX, etc... */ + +#ifndef max +# define max(a,b) ((a) > (b) ? (a) : (b)) +#endif /* !max */ + +char *AXIS2_CALL +axutil_uuid_get_mac_addr( +) +{ + struct ifaddrs *ifap; + struct ifaddrs *ifap_head; + const struct sockaddr_dl *sdl; + unsigned char *ucp; + int i; + char *data_ptr; + + if (getifaddrs(&ifap_head) < 0) + return NULL; + for (ifap = ifap_head; ifap != NULL; ifap = ifap->ifa_next) + { + if (ifap->ifa_addr != NULL && ifap->ifa_addr->sa_family == AF_LINK) + { + sdl = (const struct sockaddr_dl *) (void *) ifap->ifa_addr; + ucp = (unsigned char *) (sdl->sdl_data + sdl->sdl_nlen); + if (sdl->sdl_alen > 0) + { + data_ptr = malloc(6 * sizeof(char)); + for (i = 0; i < 6 && i < sdl->sdl_alen; i++, ucp++) + data_ptr[i] = (unsigned char) (*ucp & 0xff); + + freeifaddrs(ifap_head); + return data_ptr; + } + } + } + freeifaddrs(ifap_head); + return NULL; +} +# else /* Solaris-ish */ + +/* code modified from that posted on: + * http://forum.sun.com/jive/thread.jspa?threadID=84804&tstart=30 + */ + +char *AXIS2_CALL +axutil_uuid_get_mac_addr() +{ + char hostname[MAXHOSTNAMELEN]; + char *data_ptr; + struct hostent *he; + struct arpreq ar; + struct sockaddr_in *sa; + int s; + int i; + + if(gethostname(hostname, sizeof(hostname)) < 0) + return NULL; + if((he = gethostbyname(hostname)) == NULL) + return NULL; + if((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + return NULL; + memset(&ar, 0, sizeof(ar)); + sa = (struct sockaddr_in *)((void *)&(ar.arp_pa)); + sa->sin_family = AF_INET; + memcpy(&(sa->sin_addr), *(he->h_addr_list), sizeof(struct in_addr)); + if(ioctl(s, SIOCGARP, &ar) < 0) + { + close(s); + return NULL; + } + close(s); + if(!(ar.arp_flags & ATF_COM)) + return NULL; + data_ptr = malloc(6 * sizeof(char)); + for(i = 0; i < 6; i++) + data_ptr[i] = (unsigned char)(ar.arp_ha.sa_data[i] & 0xff); + + return data_ptr; +} +# endif +#endif diff --git a/util/src/platforms/windows/axutil_windows.c b/util/src/platforms/windows/axutil_windows.c new file mode 100644 index 0000000..e2abb5d --- /dev/null +++ b/util/src/platforms/windows/axutil_windows.c @@ -0,0 +1,93 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 <windows/axutil_windows.h>
+#include <stdio.h>
+
+
+/*
+
+std::string* getPlatformErrorMessage(long errorNumber)
+{
+ std::string* returningString = new std::string();
+ LPVOID lpMsgBuf;
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ errorNumber,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf,
+ 0, NULL );
+
+ returningString->append((LPTSTR)lpMsgBuf);
+ LocalFree(lpMsgBuf);
+
+ return returningString;
+}
+ */
+AXIS2_EXTERN HMODULE AXIS2_CALL
+callLoadLib(
+ char *lib)
+{
+ /* Disable display of the critical-error-handler message box */
+ SetErrorMode(SEM_FAILCRITICALERRORS);
+ return LoadLibraryEx(lib, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+}
+
+AXIS2_EXTERN struct tm *AXIS2_CALL
+axis2_win_gmtime(
+ const time_t * timep,
+ struct tm *result)
+{
+ return gmtime(timep);
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axutil_win32_get_last_error(
+ axis2_char_t *buf,
+ unsigned int buf_size)
+{
+ LPVOID lpMsgBuf;
+ int rc = GetLastError();
+ sprintf(buf, "DLL Load Error %d: ", rc);
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, rc, 0,
+ (LPTSTR) & lpMsgBuf, 0, NULL);
+ if(lpMsgBuf)
+ {
+ strncat(buf, (char*)lpMsgBuf, buf_size - strlen(buf) - 1);
+ }
+ LocalFree(lpMsgBuf);
+}
+
+AXIS2_EXTERN void AXIS2_CALL
+axutil_win32_get_last_wsa_error(
+ axis2_char_t *buf,
+ unsigned int buf_size)
+{
+ LPVOID lpMsgBuf;
+ int rc = WSAGetLastError();
+ sprintf(buf, "Winsock error %d: ", rc);
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, rc, 0,
+ (LPTSTR) & lpMsgBuf, 0, NULL);
+ if(lpMsgBuf)
+ {
+ strncat(buf, (char*)lpMsgBuf, buf_size - strlen(buf) - 1);
+ }
+ LocalFree(lpMsgBuf);
+}
diff --git a/util/src/platforms/windows/date_time_util_windows.c b/util/src/platforms/windows/date_time_util_windows.c new file mode 100644 index 0000000..c07903b --- /dev/null +++ b/util/src/platforms/windows/date_time_util_windows.c @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 <platforms/windows/axutil_date_time_util_windows.h> + +AXIS2_EXTERN int AXIS2_CALL +axis2_platform_get_milliseconds() +{ + struct _timeb timebuffer; + char *timeline; + int milliseconds = 0; + + _ftime(&timebuffer); + timeline = ctime(&(timebuffer.time)); + milliseconds = timebuffer.millitm; + + return milliseconds; +} diff --git a/util/src/platforms/windows/dir_windows.c b/util/src/platforms/windows/dir_windows.c new file mode 100644 index 0000000..1e0ad8f --- /dev/null +++ b/util/src/platforms/windows/dir_windows.c @@ -0,0 +1,272 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 <malloc.h> +#include <string.h> +#include <errno.h> + +#include <platforms/windows/axutil_dir_windows.h> + +/*dirent.h style mehtods for win32*/ + +AXIS2_DIR *AXIS2_CALL +axis2_opendir( + const char *_dirname) +{ + AXIS2_DIR *dirp; + char *filespec; + long handle; + int index; + + filespec = malloc(strlen(_dirname) + 2 + 1); + strcpy(filespec, _dirname); + index = (int)strlen(filespec) - 1; + if(index >= 0 && (filespec[index] == '/' || (filespec[index] == '\\' && !IsDBCSLeadByte( + filespec[index - 1])))) + filespec[index] = '\0'; + strcat(filespec, "/*"); + + dirp = (AXIS2_DIR *)malloc(sizeof(AXIS2_DIR)); + dirp->offset = 0; + dirp->finished = 0; + + if((handle = (long)_findfirst(filespec, &(dirp->fileinfo))) < 0) + /* We are sure that the difference lies within the long range */ + { + if(errno == ENOENT || errno == EINVAL) + dirp->finished = 1; + else + { + free(dirp); + free(filespec); + return NULL; + } + } + /* We are using the ISO C++ conformant name: _strdup, as demanded by VS 2005 */ + dirp->dirname = _strdup(_dirname); + dirp->handle = handle; + free(filespec); + + return dirp; +} + +int AXIS2_CALL +axis2_closedir( + AXIS2_DIR * _dirp) +{ + int iret = -1; + if(!_dirp) + return iret; + iret = _findclose(_dirp->handle); + if(_dirp->dirname) + free(_dirp->dirname); + if(_dirp) + free(_dirp); + + return iret; +} + +struct dirent *AXIS2_CALL +axis2_readdir( + AXIS2_DIR * _dirp) +{ + if(!_dirp || _dirp->finished) + return NULL; + + if(_dirp->offset != 0) + { + if(_findnext(_dirp->handle, &(_dirp->fileinfo)) < 0) + { + _dirp->finished = 1; + return NULL; + } + } + _dirp->offset++; + + strcpy(_dirp->dent.d_name, _dirp->fileinfo.name); /*, _MAX_FNAME+1); */ + _dirp->dent.d_ino = 1; + _dirp->dent.d_reclen = (unsigned short)strlen(_dirp->dent.d_name); + _dirp->dent.d_off = _dirp->offset; + + return &(_dirp->dent); +} + +int AXIS2_CALL +axis2_readdir_r( + AXIS2_DIR * _dirp, + struct dirent *_entry, + struct dirent **__result) +{ + if(!_dirp || _dirp->finished) + { + *__result = NULL; + return -1; + } + + if(_dirp->offset != 0) + { + if(_findnext(_dirp->handle, &(_dirp->fileinfo)) < 0) + { + _dirp->finished = 1; + *__result = NULL; + return -1; + } + } + _dirp->offset++; + + strcpy(_dirp->dent.d_name, _dirp->fileinfo.name); /*, _MAX_FNAME+1); */ + _dirp->dent.d_ino = 1; + _dirp->dent.d_reclen = (unsigned short)strlen(_dirp->dent.d_name); + _dirp->dent.d_off = _dirp->offset; + + memcpy(_entry, &_dirp->dent, sizeof(*_entry)); + + *__result = &_dirp->dent; + + return 0; +} + +int AXIS2_CALL +axis2_rewinddir( + AXIS2_DIR * dirp) +{ + char *filespec; + long handle; + int index; + + _findclose(dirp->handle); + + dirp->offset = 0; + dirp->finished = 0; + + filespec = malloc(strlen(dirp->dirname) + 2 + 1); + strcpy(filespec, dirp->dirname); + index = (int)(strlen(filespec) - 1); + if(index >= 0 && (filespec[index] == '/' || filespec[index] == '\\')) + filespec[index] = '\0'; + strcat(filespec, "/*"); + + if((handle = (long)_findfirst(filespec, &(dirp->fileinfo))) < 0) + /* We are sure that the difference lies within the int range */ + { + if(errno == ENOENT || errno == EINVAL) + dirp->finished = 1; + } + dirp->handle = handle; + free(filespec); + + return 0; +} + +int +alphasort( + const struct dirent **__d1, + const struct dirent **__d2) +{ + return strcoll((*__d1)->d_name, (*__d2)->d_name); +} + +int AXIS2_CALL +axis2_scandir( + const char *_dirname, + struct dirent **__namelist[], + int + (*selector)( + const struct dirent * entry), + int + (*compare)( + const struct dirent ** __d1, + const struct dirent ** __d2)) +{ + AXIS2_DIR *dirp = NULL; + struct dirent **vector = NULL; + struct dirent *dp = NULL; + int vector_size = 0; + int nfiles = 0; + + if(__namelist == NULL) + { + return -1; + } + dirp = axis2_opendir(_dirname); + if(!dirp) + { + return -1; + } + dp = axis2_readdir(dirp); + while(dp) + { + int dsize = 0; + struct dirent *newdp = NULL; + + if(selector && (*selector)(dp) == 0) + { + dp = axis2_readdir(dirp); + continue; + } + + if(nfiles == vector_size) + { + struct dirent **newv; + if(vector_size == 0) + { + vector_size = 10; + } + else + { + vector_size *= 2; + } + + newv = (struct dirent **)realloc(vector, vector_size * sizeof(struct dirent *)); + if(!newv) + { + return -1; + } + vector = newv; + } + + /*dsize = + (int) sizeof(struct dirent) + + (int) ((strlen(dp->d_name) + 1) * sizeof(char));*/ + dsize = (int)sizeof(struct dirent); + newdp = (struct dirent *)malloc(dsize); + + if(newdp == NULL) + { + while(nfiles-- > 0) + { + free(vector[nfiles]); + } + free(vector); + return -1; + } + + vector[nfiles++] = (struct dirent *)memcpy(newdp, dp, dsize); + dp = axis2_readdir(dirp); + } + + axis2_closedir(dirp); + + *__namelist = vector; + + if(compare) + { + qsort(*__namelist, nfiles, sizeof(struct dirent *), compare); + } + + return nfiles; +} diff --git a/util/src/platforms/windows/getopt_windows.c b/util/src/platforms/windows/getopt_windows.c new file mode 100644 index 0000000..6f5e18b --- /dev/null +++ b/util/src/platforms/windows/getopt_windows.c @@ -0,0 +1,137 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 <stdlib.h> +#include <string.h> +#include <stdio.h> + +#ifndef AXIS2_GET_OPT_DEFINE_MODE_NO_IMPORT +/* Required by "axutil_getopt_windows.h" */ +#define AXIS2_GET_OPT_DEFINE_MODE_NO_IMPORT +#endif +#include <platforms/windows/axutil_getopt_windows.h> + +int optind = 1; +int opterr = 1; +int optopt; +char *optarg; + +#define AXIS2_OPT_ERR_NO_ARG 1 +#define AXIS2_OPT_ERR_INVALID_OPTION 2 +#define AXIS2_OPT_ERR_BAD_ARG 3 + +int +_axis2_opt_error( + int __optopt, + int __err, + int __showerr) +{ + switch(__err) + { + case AXIS2_OPT_ERR_NO_ARG: + if(__showerr) + fprintf(stderr, " option requires an argument -- %c\n", __optopt); + break; + case AXIS2_OPT_ERR_INVALID_OPTION: + if(__showerr) + fprintf(stderr, " illegal option -- %c\n", __optopt); + break; + case AXIS2_OPT_ERR_BAD_ARG: + return (int)':'; + default: + if(__showerr) + fprintf(stderr, "unknown\n"); + } + return (int)'?'; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_getopt( + int __argc, + char * const *__argv, + const char *__shortopts) +{ + static char *pos = ""; + char *olstindex = NULL; + + if(!*pos) + { + /* no option or invalid option */ + if(optind >= __argc || *(pos = __argv[optind]) != '-') + { + pos = ""; + return -1; + } + + /*-- option*/ + if(pos[1] && *++pos == '-') + { + ++optind; + pos = ""; + return -1; + } + } + + if((optopt = (int)*pos++) == (int)':') + { + if(optopt == (int)'-') + return -1; + if(!*pos) + ++optind; + if(*__shortopts != ':') + return _axis2_opt_error(optopt, AXIS2_OPT_ERR_BAD_ARG, opterr); + _axis2_opt_error(optopt, AXIS2_OPT_ERR_INVALID_OPTION, opterr); + } + else + { + olstindex = strchr(__shortopts, optopt); + if(!olstindex) + { + if(optopt == (int)'-') + return -1; + if(!*pos) + ++optind; + if(*__shortopts != ':') + return _axis2_opt_error(optopt, AXIS2_OPT_ERR_BAD_ARG, opterr); + _axis2_opt_error(optopt, AXIS2_OPT_ERR_INVALID_OPTION, opterr); + } + } + + if(!olstindex || *++olstindex != ':') + { + optarg = NULL; + if(!*pos) + ++optind; + } + else + { + if(*pos) + optarg = pos; + else if(__argc <= ++optind) + { + pos = ""; + if(*__shortopts == ':') + return _axis2_opt_error(-1, AXIS2_OPT_ERR_BAD_ARG, opterr); + return _axis2_opt_error(optopt, AXIS2_OPT_ERR_NO_ARG, opterr); + } + else + optarg = __argv[optind]; + pos = ""; + ++optind; + } + return optopt; +} diff --git a/util/src/platforms/windows/thread_mutex_windows.c b/util/src/platforms/windows/thread_mutex_windows.c new file mode 100644 index 0000000..13df497 --- /dev/null +++ b/util/src/platforms/windows/thread_mutex_windows.c @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 <axutil_thread.h> +#include <platforms/windows/axutil_thread_mutex_windows.h> + +static axis2_status_t +thread_mutex_cleanup( + void *data) +{ + axutil_thread_mutex_t *lock = NULL; + axutil_allocator_t *allocator = NULL; + if(!data) + return AXIS2_FAILURE; + + lock = (axutil_thread_mutex_t *)data; + allocator = lock->allocator; + + if(lock->type == thread_mutex_critical_section) + { + DeleteCriticalSection(&lock->section); + } + else + { + if(!CloseHandle(lock->handle)) + { + return AXIS2_FAILURE; + } + } + + AXIS2_FREE(allocator, lock); + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axutil_thread_mutex_t *AXIS2_CALL +axutil_thread_mutex_create( + axutil_allocator_t * allocator, + unsigned int flags) +{ + axutil_thread_mutex_t *mutex = NULL; + + mutex = (axutil_thread_mutex_t *)AXIS2_MALLOC(allocator, sizeof(axutil_thread_mutex_t)); + mutex->allocator = allocator; + + if(flags == AXIS2_THREAD_MUTEX_DEFAULT) /*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_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_mutex_lock( + axutil_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_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_mutex_trylock( + axutil_thread_mutex_t * mutex) +{ + + if(mutex->type == thread_mutex_critical_section) + { + /* TODO :implement trylock for critical section */ + } + 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_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_mutex_unlock( + axutil_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_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_mutex_destroy( + axutil_thread_mutex_t * mutex) +{ + return thread_mutex_cleanup((void *)mutex); +} diff --git a/util/src/platforms/windows/thread_windows.c b/util/src/platforms/windows/thread_windows.c new file mode 100644 index 0000000..67af332 --- /dev/null +++ b/util/src/platforms/windows/thread_windows.c @@ -0,0 +1,326 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 <axutil_utils.h> +#include <platforms/windows/axutil_thread_windows.h> + +DWORD tls_axutil_thread = 0; + +AXIS2_EXTERN axutil_threadattr_t *AXIS2_CALL +axutil_threadattr_create( + axutil_allocator_t * allocator) +{ + axutil_threadattr_t *new = NULL; + + new = AXIS2_MALLOC(allocator, sizeof(axutil_threadattr_t)); + if(!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_EXTERN axis2_status_t AXIS2_CALL +threadattr_cleanup( + void *data) +{ + /*axutil_threadattr_t *attr = data;*/ + /*nothing to clean up */ + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_threadattr_detach_set( + axutil_threadattr_t * attr, + axis2_bool_t detached) +{ + attr->detach = detached; + return AXIS2_SUCCESS; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_threadattr_detach_get( + axutil_threadattr_t * attr, + const axutil_env_t * env) +{ + if(1 == attr->detach) + { + return AXIS2_TRUE; + } + return AXIS2_FALSE; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_threadattr_stacksize_set( + axutil_threadattr_t * attr, + size_t stacksize) +{ + attr->stacksize = stacksize; + return AXIS2_SUCCESS; +} + +static void * +dummy_worker( + void *opaque) +{ + axutil_thread_t *thd = (axutil_thread_t *)opaque; + TlsSetValue(tls_axutil_thread, thd->td); + return thd->func(thd, thd->data); +} + +AXIS2_EXTERN axutil_thread_t *AXIS2_CALL +axutil_thread_create( + axutil_allocator_t * allocator, + axutil_threadattr_t * attr, + axutil_thread_start_t func, + void *data) +{ + HANDLE handle; + unsigned long temp; + axutil_thread_t *new = NULL; + + new = (axutil_thread_t *)AXIS2_MALLOC(allocator, sizeof(axutil_thread_t)); + + if(!new) + { + return NULL; + } + + new->data = data; + new->func = func; + new->td = NULL; + new->try_exit = AXIS2_FALSE; + + /* 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 long (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_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_exit( + axutil_thread_t * thd, + axutil_allocator_t * allocator) +{ + axis2_status_t status = AXIS2_SUCCESS; + + if(thd) + { + if(thd->td && (axis2_os_thread_current() != thd->td)) + { + TerminateThread(thd->td, 0); + axutil_thread_join(thd); + AXIS2_FREE(allocator, thd); + return status; + } + AXIS2_FREE(allocator, thd); + } + if(status) + { + ExitThread(0); + } + + return status; +} + +AXIS2_EXTERN axis2_os_thread_t AXIS2_CALL +axis2_os_thread_current( + void) +{ + HANDLE hthread = (HANDLE)TlsGetValue(tls_axutil_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_axutil_thread, hthread); + return hthread; +} + +AXIS2_EXTERN int AXIS2_CALL +axis2_os_thread_equal( + axis2_os_thread_t tid1, + axis2_os_thread_t tid2) +{ + return (tid1 == tid2); +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_join( + axutil_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_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_detach( + axutil_thread_t * thd) +{ + if(thd->td && CloseHandle(thd->td)) + { + thd->td = NULL; + return AXIS2_SUCCESS; + } + else + { + return AXIS2_FAILURE; + } +} + +AXIS2_EXTERN axis2_os_thread_t AXIS2_CALL +axis2_os_thread_get( + axutil_thread_t * thd, + const axutil_env_t * env) +{ + return thd->td; +} + +/** + * function is used to allocate a new key. This key now becomes valid for all threads in our process. + * When a key is created, the value it points to defaults to NULL. Later on each thread may change + * its copy of the value as it wishes. + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_key_create( + axutil_threadkey_t * axis2_key) +{ + DWORD tls_key = axis2_key->key; + if ((tls_key = TlsAlloc()) == TLS_OUT_OF_INDEXES) + { + return AXIS2_FAILURE; + } + else + { + return AXIS2_SUCCESS; + } +} + +/** + * This function is used to get the value of a given key + * @return void*. A key's value is simply a void pointer (void*) + */ +AXIS2_EXTERN void *AXIS2_CALL +axutil_thread_getspecific( + axutil_threadkey_t * axis2_key) +{ + void *value = NULL; + DWORD tls_key = axis2_key->key; + value = TlsGetValue(tls_key); + return value; +} + +/** + * This function is used to get the value of a given key + * @param keys value. A key's value is simply a void pointer (void*), so we can + * store in it anything that we want + */ +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_setspecific( + axutil_threadkey_t * axis2_key, + void *value) +{ + DWORD tls_key = axis2_key->key; + if(!TlsSetValue(tls_key, value)) + { + return AXIS2_FAILURE; + } + else + { + return AXIS2_SUCCESS; + } +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_thread_key_free( + axutil_threadkey_t * axis2_key) +{ + DWORD tls_key = axis2_key->key; + TlsFree(tls_key); +} + +AXIS2_EXTERN axutil_thread_once_t *AXIS2_CALL +axutil_thread_once_init( + axutil_allocator_t * allocator) +{ + axutil_thread_once_t *control = NULL; + control = AXIS2_MALLOC(allocator, sizeof(*control)); + if(control) + { + control->value = 0; + } + return control; +} + +AXIS2_EXTERN axis2_status_t AXIS2_CALL +axutil_thread_once( + axutil_thread_once_t * control, + void + (*func)( + void)) +{ + if(!InterlockedExchange(&control->value, 1)) + { + func(); + } + return AXIS2_SUCCESS; +} diff --git a/util/src/platforms/windows/uuid_gen_windows.c b/util/src/platforms/windows/uuid_gen_windows.c new file mode 100644 index 0000000..c075746 --- /dev/null +++ b/util/src/platforms/windows/uuid_gen_windows.c @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 <platforms/windows/axutil_uuid_gen_windows.h> +#include <rpc.h> +#include <stdio.h> +#include <string.h> +#include <axutil_utils_defines.h> + +AXIS2_EXTERN axis2_char_t * AXIS2_CALL +axutil_platform_uuid_gen( + char *s) +{ + RPC_STATUS retval; + UUID uuid; + unsigned char *str; + axis2_char_t * retstr; + + if(!s) + { + return NULL; + } + + retstr = s; + retval = UuidCreate(&uuid); + if(retval == RPC_S_UUID_LOCAL_ONLY) + { + printf("warning - unique within computer \n"); + } + else if(retval == RPC_S_UUID_NO_ADDRESS) + { + return NULL; + } + + retval = UuidToStringA(&uuid, &str); + + if(retval == RPC_S_OK) + { + strcpy(retstr, (char *)str); + RpcStringFree(&str); + } + else if(retval == RPC_S_OUT_OF_MEMORY) + { + return NULL; + } + return retstr; +} |