| /* Copyright (C) 2001 by First Peer, Inc. All rights reserved. |
| ** |
| ** Redistribution and use in source and binary forms, with or without |
| ** modification, are permitted provided that the following conditions |
| ** are met: |
| ** 1. Redistributions of source code must retain the above copyright |
| ** notice, this list of conditions and the following disclaimer. |
| ** 2. Redistributions in binary form must reproduce the above copyright |
| ** notice, this list of conditions and the following disclaimer in the |
| ** documentation and/or other materials provided with the distribution. |
| ** 3. The name of the author may not be used to endorse or promote products |
| ** derived from this software without specific prior written permission. |
| ** |
| ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| ** SUCH DAMAGE. */ |
| |
| #include "xmlrpc_config.h" |
| |
| #undef PACKAGE |
| #undef VERSION |
| |
| #include <stddef.h> |
| #include <string.h> |
| #include <stdlib.h> |
| |
| #ifdef WIN32 |
| #ifdef _DEBUG |
| # include <crtdbg.h> |
| # define new DEBUG_NEW |
| # define malloc(size) _malloc_dbg( size, _NORMAL_BLOCK, __FILE__, __LINE__) |
| # undef THIS_FILE |
| static char THIS_FILE[] = __FILE__; |
| #endif |
| #endif /*WIN32*/ |
| |
| #include "xmlrpc.h" |
| #include "xmlrpc_client.h" |
| |
| #if defined (WIN32) |
| #include <process.h> |
| #endif |
| |
| /* For debugging the xmlrpc_transport threading. */ |
| /* #define tdbg_printf printf */ |
| #define tdbg_printf (void *) |
| |
| /* Lacking from the abyss/thread.c implimentaion. */ |
| void wait_for_asynch_thread(pthread_t *thread) |
| { |
| #if WIN32 |
| unsigned long milliseconds = INFINITE; |
| switch (WaitForSingleObject ( |
| *thread /* handle to object to wait for */, |
| milliseconds /* time-out interval in milliseconds*/) ) |
| { |
| /* One may want to handle these cases */ |
| case WAIT_OBJECT_0: |
| case WAIT_TIMEOUT: |
| break; |
| } |
| #else |
| void * result; |
| int success; |
| success = pthread_join (*thread, &result); |
| #endif |
| } |
| |
| /* MRB-WARNING: Only call when you have successfully |
| ** acquired the Lock/Unlock mutex! */ |
| void unregister_asynch_thread (running_thread_list *list, pthread_t *thread) |
| { |
| running_thread_info * pCur = NULL; |
| XMLRPC_ASSERT_PTR_OK(thread); |
| XMLRPC_ASSERT_PTR_OK(list); |
| |
| tdbg_printf("unregister_asynch_thread: &pthread_id = %08X *(%08X)\n", thread, *thread); |
| /* Removal */ |
| /* Lock (); */ |
| for (pCur = list->AsyncThreadHead; pCur != NULL; pCur = (running_thread_info *)pCur->Next) |
| { |
| if (pCur->_thread == *thread) |
| { |
| if (pCur == list->AsyncThreadHead) |
| list->AsyncThreadHead = pCur->Next; |
| if (pCur == list->AsyncThreadTail) |
| list->AsyncThreadTail = pCur->Last; |
| if (pCur->Last) |
| ((running_thread_info *)(pCur->Last))->Next = pCur->Next; |
| if (pCur->Next) |
| ((running_thread_info *)(pCur->Next))->Last = pCur->Last; |
| /* Free malloc'd running_thread_info */ |
| free (pCur); |
| return; |
| } |
| } |
| |
| /* This is a serious progmatic error, since the thread |
| ** should be in that list! */ |
| XMLRPC_ASSERT_PTR_OK(0x0000); |
| |
| /* Unlock (); */ |
| } |
| |
| /* MRB-WARNING: Only call when you have successfully |
| ** acquired the Lock/Unlock mutex! */ |
| void register_asynch_thread (running_thread_list *list, pthread_t *thread) |
| { |
| running_thread_info* info = (running_thread_info *) malloc(sizeof(running_thread_info)); |
| |
| XMLRPC_ASSERT_PTR_OK(thread); |
| XMLRPC_ASSERT_PTR_OK(list); |
| |
| tdbg_printf("register_asynch_thread: &pthread_id = %08X *(%08X)\n", thread, *thread); |
| |
| info->_thread = *thread; |
| |
| /* Insertion */ |
| /* Lock (); */ |
| if (list->AsyncThreadHead == NULL) |
| { |
| list->AsyncThreadHead = list->AsyncThreadTail = info; |
| list->AsyncThreadTail->Next = list->AsyncThreadHead->Next = NULL; |
| list->AsyncThreadTail->Last = list->AsyncThreadHead->Last = NULL; |
| } |
| else |
| { |
| info->Last = list->AsyncThreadTail; |
| list->AsyncThreadTail->Next = info; |
| list->AsyncThreadTail = list->AsyncThreadTail->Next; |
| list->AsyncThreadTail->Next = NULL; |
| } |
| /* Unlock (); */ |
| } |