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 ro...@apache.org on 2004/06/23 14:20:19 UTC
cvs commit: ws-axis/c/tests/client/threadSafe/WinClient WinClient.dsw WinClient.dsp Thread.h StdAfx.h StdAfx.cpp Calculator.h Calculator.cpp
roshan 2004/06/23 05:20:19
Added: c/tests/client/threadSafe/WinClient WinClient.dsw
WinClient.dsp Thread.h StdAfx.h StdAfx.cpp
Calculator.h Calculator.cpp
Log:
Adding a client sample for testing threadsafty
Revision Changes Path
1.1 ws-axis/c/tests/client/threadSafe/WinClient/WinClient.dsw
Index: WinClient.dsw
===================================================================
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "WinClient"=".\WinClient.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
1.1 ws-axis/c/tests/client/threadSafe/WinClient/WinClient.dsp
Index: WinClient.dsp
===================================================================
# Microsoft Developer Studio Project File - Name="WinClient" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=WinClient - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "WinClient.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "WinClient.mak" CFG="WinClient - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "WinClient - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "WinClient - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "WinClient - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "WinClient - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib AxisClient.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../../../bin/WinClient.exe" /pdbtype:sept /libpath:"../../../../bin"
!ENDIF
# Begin Target
# Name "WinClient - Win32 Release"
# Name "WinClient - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\..\..\src\common\AxisException.cpp
# End Source File
# Begin Source File
SOURCE=.\Calculator.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\..\..\..\include\axis\server\AxisException.h
# End Source File
# Begin Source File
SOURCE=.\Calculator.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# Begin Source File
SOURCE=.\Thread.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project
1.1 ws-axis/c/tests/client/threadSafe/WinClient/Thread.h
Index: Thread.h
===================================================================
#ifndef __THREAD_H__
#define __THREAD_H__
class CThread
{
public:
/*
* Info: Default Constructor
*/
CThread()
{
m_pThreadFunc = CThread::EntryPoint; // Can call Detach() also.
}
/*
* Info: Plug Constructor
*
* Use this to migrate/port existing worker threads to objects immediately
* Although you lose the benefits of ThreadCTOR and ThreadDTOR.
*/
CThread(LPTHREAD_START_ROUTINE lpExternalRoutine)
{
Attach(lpExternalRoutine);
}
/*
* Info: Default Destructor
*
* I think it is wise to destroy the thread even if it is running,
* when the main thread reaches here.
*/
~CThread()
{
if ( m_ThreadCtx.m_hThread )
Stop(true);
}
/*
* Info: Starts the thread.
*
* This function starts the thread pointed by m_pThreadFunc with default attributes
*/
DWORD Start( void* arg = NULL )
{
m_ThreadCtx.m_pUserData = arg;
m_ThreadCtx.m_hThread = CreateThread(NULL, 0, m_pThreadFunc, this, 0, &m_ThreadCtx.m_dwTID);
m_ThreadCtx.m_dwExitCode = (DWORD)-1;
return GetLastError();
}
/*
* Info: Stops the thread.
*
* This function stops the current thread.
* We can force kill a thread which results in a TerminateThread.
*/
DWORD Stop ( bool bForceKill = false )
{
if ( m_ThreadCtx.m_hThread )
{
GetExitCodeThread(m_ThreadCtx.m_hThread, &m_ThreadCtx.m_dwExitCode);
if ( m_ThreadCtx.m_dwExitCode == STILL_ACTIVE && bForceKill )
TerminateThread(m_ThreadCtx.m_hThread, DWORD(-1));
m_ThreadCtx.m_hThread = NULL;
}
return m_ThreadCtx.m_dwExitCode;
}
/*
* Info: Starts the thread.
*
* This function starts the thread pointed by m_pThreadFunc with default attributes
*/
DWORD GetExitCode() const
{
if ( m_ThreadCtx.m_hThread )
GetExitCodeThread(m_ThreadCtx.m_hThread, (LPDWORD)&m_ThreadCtx.m_dwExitCode);
return m_ThreadCtx.m_dwExitCode;
}
/*
* Info: Attaches a Thread Function
*
* Used primarily for porting but can serve in developing generic thread objects
*/
void Attach( LPTHREAD_START_ROUTINE lpThreadFunc ){
m_pThreadFunc = lpThreadFunc;
}
/*
* Info: Detaches the Attached Thread Function
*
* Detaches the Attached Thread Function, If any.
* by resetting the thread function pointer to EntryPoint1
*/
void Detach( void ){
m_pThreadFunc = CThread::EntryPoint;
}
protected:
/*
* Info: DONT override this method.
*
* This function is like a standard template.
* Override if you are sure of what you are doing.
*/
static DWORD WINAPI EntryPoint( LPVOID pArg)
{
CThread *pParent = reinterpret_cast<CThread*>(pArg);
pParent->ThreadCtor();
pParent->Run( pParent->m_ThreadCtx.m_pUserData );
pParent->ThreadDtor();
return STILL_ACTIVE;
}
/*
* Info: Override this method.
*
* This function should contain the body/code of your thread.
* Notice the signature is similar to that of any worker thread function
* except for the calling convention.
*/
virtual DWORD Run( LPVOID /* arg */ )
{ return m_ThreadCtx.m_dwExitCode; }
/*
* Info: Constructor-like function.
*
* Will be called by EntryPoint before executing the thread body.
* Override this function to provide your extra initialization.
*
* NOTE: do not confuse it with the classes constructor
*/
virtual void ThreadCtor(){ }
/*
* Info: Destructor-like function.
*
* Will be called by EntryPoint after executing the thread body.
* Override this function to provide your extra destruction.
*
* NOTE: do not confuse it with the classes constructor
*/
virtual void ThreadDtor(){ }
private:
/*
* Info: Thread Context Inner Class
*
* Every thread object needs to be associated with a set of values.
* like UserData Pointer, Handle, Thread ID etc.
*
* NOTE: This class can be enhanced to varying functionalities
* eg.,
* * Members to hold StackSize
* * SECURITY_ATTRIBUTES member.
*/
class CThreadContext
{
public:
CThreadContext(){
memset(this, 0, sizeof(this));
}
/*
* Attributes Section
*/
public:
HANDLE m_hThread; // The Thread Handle
DWORD m_dwTID; // The Thread ID
LPVOID m_pUserData; // The user data pointer
LPVOID m_pParent; // The this pointer of the parent CThread object
DWORD m_dwExitCode; // The Exit Code of the thread
};
/*
* Attributes Section
*/
protected:
/*
* Info: Members of CThread
*/
CThreadContext m_ThreadCtx; // The Thread Context member
LPTHREAD_START_ROUTINE m_pThreadFunc; // The Worker Thread Function Pointer
};
#endif //__THREAD_H__
1.1 ws-axis/c/tests/client/threadSafe/WinClient/StdAfx.h
Index: StdAfx.h
===================================================================
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__8D5CB365_C92D_11D5_948D_002018C0A5DE__INCLUDED_)
#define AFX_STDAFX_H__8D5CB365_C92D_11D5_948D_002018C0A5DE__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <stdio.h>
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__8D5CB365_C92D_11D5_948D_002018C0A5DE__INCLUDED_)
1.1 ws-axis/c/tests/client/threadSafe/WinClient/StdAfx.cpp
Index: StdAfx.cpp
===================================================================
// stdafx.cpp : source file that includes just the standard includes
// C Projects.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
1.1 ws-axis/c/tests/client/threadSafe/WinClient/Calculator.h
Index: Calculator.h
===================================================================
/*
* This file was auto-generated by the Axis C++ Web Service Generator (WSDL2Ws)
* This file contains Client Stub Class for remote web service
*/
#if !defined(__CALCULATOR_CLIENTSTUB_H__INCLUDED_)
#define __CALCULATOR_CLIENTSTUB_H__INCLUDED_
#include <axis/client/Stub.h>
#include <axis/server/AxisException.h>
/*include Exception header files here*/
class Calculator :public Stub
{
public:
Calculator(const char* pchEndpointUri, AXIS_PROTOCOL_TYPE eProtocol);
Calculator();
public:
virtual ~Calculator();
public:
int add(int Value0,int Value1);
int sub(int Value0,int Value1);
int mul(int Value0,int Value1);
int div(int Value0,int Value1);
int getFaultDetail(char** ppcDetail);
};
#endif /* !defined(__CALCULATOR_CLIENTSTUB_H__INCLUDED_)*/
1.1 ws-axis/c/tests/client/threadSafe/WinClient/Calculator.cpp
Index: Calculator.cpp
===================================================================
/*
* This file was auto-generated by the Axis C++ Web Service Generator (WSDL2Ws)
* This file contains Client Stub implementation for remote web service.
*/
#include <iostream.h>
#include "Calculator.h"
#include "stdafx.h"
#include <windows.h>
#include "Thread.h"
#include <axis/server/AxisWrapperAPI.h>
using namespace std;
Calculator::Calculator(const char* pchEndpointUri, AXIS_PROTOCOL_TYPE eProtocol)
:Stub(pchEndpointUri, eProtocol)
{
}
Calculator::Calculator()
:Stub(" ", APTHTTP)
{
m_pCall->setEndpointURI("http://localhost/axis/Calculator");
}
Calculator::~Calculator()
{
}
/*Methods corresponding to the web service methods*/
/*
* This method wrap the service method add
*/
int Calculator::add(int Value0, int Value1)
{
int Ret;
char* cFaultcode;
char* cFaultstring;
char* cFaultactor;
char* cFaultdetail;
try
{
if (AXIS_SUCCESS != m_pCall->initialize(CPP_RPC_PROVIDER, NORMAL_CHANNEL))
return Ret;
m_pCall->setTransportProperty(SOAPACTION_HEADER , "Calculator#add");
m_pCall->setSOAPVersion(SOAP_VER_1_1);
m_pCall->setOperation("add", "http://localhost/axis/Calculator");
applyUserPreferences();
m_pCall->addParameter((void*)&Value0, "in0", XSD_INT);
m_pCall->addParameter((void*)&Value1, "in1", XSD_INT);
if (AXIS_SUCCESS == m_pCall->invoke())
{
if(AXIS_SUCCESS == m_pCall->checkMessage("addResponse", "http://localhost/axis/Calculator"))
{
Ret = m_pCall->getElementAsInt("addReturn", 0);
}
}
m_pCall->unInitialize();
return Ret;
}
catch(AxisException& e)
{
int iExceptionCode = e.getExceptionCode();
if(AXISC_NODE_VALUE_MISMATCH_EXCEPTION != iExceptionCode)
{
throw;
}
else if (AXIS_SUCCESS == m_pCall->checkFault("Fault","http://localhost/axis/Calculator" ))//Exception handling code goes here
{
cFaultcode = m_pCall->getElementAsString("faultcode", 0);
cFaultstring = m_pCall->getElementAsString("faultstring", 0);
cFaultactor = m_pCall->getElementAsString("faultactor", 0);
cFaultdetail = m_pCall->getElementAsString("faultdetail", 0);
throw AxisException(cFaultdetail);
}
else throw;
}
}
/*
* This method wrap the service method sub
*/
int Calculator::sub(int Value0, int Value1)
{
int Ret;
char* cFaultcode;
char* cFaultstring;
char* cFaultactor;
char* cFaultdetail;
try
{
if (AXIS_SUCCESS != m_pCall->initialize(CPP_RPC_PROVIDER, NORMAL_CHANNEL))
return Ret;
m_pCall->setTransportProperty(SOAPACTION_HEADER , "Calculator#sub");
m_pCall->setSOAPVersion(SOAP_VER_1_1);
m_pCall->setOperation("sub", "http://localhost/axis/Calculator");
applyUserPreferences();
m_pCall->addParameter((void*)&Value0, "in0", XSD_INT);
m_pCall->addParameter((void*)&Value1, "in1", XSD_INT);
if (AXIS_SUCCESS == m_pCall->invoke())
{
if(AXIS_SUCCESS == m_pCall->checkMessage("subResponse", "http://localhost/axis/Calculator"))
{
Ret = m_pCall->getElementAsInt("subReturn", 0);
}
}
m_pCall->unInitialize();
return Ret;
}
catch(AxisException& e)
{
int iExceptionCode = e.getExceptionCode();
if(AXISC_NODE_VALUE_MISMATCH_EXCEPTION != iExceptionCode)
{
throw;
}
else if (AXIS_SUCCESS == m_pCall->checkFault("Fault","http://localhost/axis/Calculator" ))//Exception handling code goes here
{
cFaultcode = m_pCall->getElementAsString("faultcode", 0);
cFaultstring = m_pCall->getElementAsString("faultstring", 0);
cFaultactor = m_pCall->getElementAsString("faultactor", 0);
cFaultdetail = m_pCall->getElementAsString("faultdetail", 0);
throw AxisException(cFaultdetail);
}
else throw;
}
}
/*
* This method wrap the service method mul
*/
int Calculator::mul(int Value0, int Value1)
{
int Ret;
char* cFaultcode;
char* cFaultstring;
char* cFaultactor;
char* cFaultdetail;
try
{
if (AXIS_SUCCESS != m_pCall->initialize(CPP_RPC_PROVIDER, NORMAL_CHANNEL))
return Ret;
m_pCall->setTransportProperty(SOAPACTION_HEADER , "Calculator#mul");
m_pCall->setSOAPVersion(SOAP_VER_1_1);
m_pCall->setOperation("mul", "http://localhost/axis/Calculator");
applyUserPreferences();
m_pCall->addParameter((void*)&Value0, "in0", XSD_INT);
m_pCall->addParameter((void*)&Value1, "in1", XSD_INT);
if (AXIS_SUCCESS == m_pCall->invoke())
{
if(AXIS_SUCCESS == m_pCall->checkMessage("mulResponse", "http://localhost/axis/Calculator"))
{
Ret = m_pCall->getElementAsInt("addReturn", 0);
}
}
m_pCall->unInitialize();
return Ret;
}
catch(AxisException& e)
{
int iExceptionCode = e.getExceptionCode();
if(AXISC_NODE_VALUE_MISMATCH_EXCEPTION != iExceptionCode)
{
throw;
}
else if (AXIS_SUCCESS == m_pCall->checkFault("Fault","http://localhost/axis/Calculator" ))//Exception handling code goes here
{
cFaultcode = m_pCall->getElementAsString("faultcode", 0);
cFaultstring = m_pCall->getElementAsString("faultstring", 0);
cFaultactor = m_pCall->getElementAsString("faultactor", 0);
cFaultdetail = m_pCall->getElementAsString("faultdetail", 0);
throw AxisException(cFaultdetail);
}
else throw;
}
}
/*
* This method wrap the service method div
*/
int Calculator::div(int Value0, int Value1)
{
int Ret;
char* cFaultcode;
char* cFaultstring;
char* cFaultactor;
char* cFaultdetail;
try
{
if (AXIS_SUCCESS != m_pCall->initialize(CPP_RPC_PROVIDER, NORMAL_CHANNEL))
return Ret;
m_pCall->setTransportProperty(SOAPACTION_HEADER , "Calculator#div");
m_pCall->setSOAPVersion(SOAP_VER_1_1);
m_pCall->setOperation("div", "http://localhost/axis/Calculator");
applyUserPreferences();
m_pCall->addParameter((void*)&Value0, "in0", XSD_INT);
m_pCall->addParameter((void*)&Value1, "in1", XSD_INT);
if (AXIS_SUCCESS == m_pCall->invoke())
{
if(AXIS_SUCCESS == m_pCall->checkMessage("divResponse", "http://localhost/axis/Calculator"))
{
Ret = m_pCall->getElementAsInt("addReturn", 0);
}
}
m_pCall->unInitialize();
return Ret;
}
catch(AxisException& e)
{
int iExceptionCode = e.getExceptionCode();
if(AXISC_NODE_VALUE_MISMATCH_EXCEPTION != iExceptionCode)
{
throw;
}
else if (AXIS_SUCCESS == m_pCall->checkFault("Fault","http://localhost/axis/Calculator" ))//Exception handling code goes here
{
cFaultcode = m_pCall->getElementAsString("faultcode", 0);
cFaultstring = m_pCall->getElementAsString("faultstring", 0);
cFaultactor = m_pCall->getElementAsString("faultactor", 0);
cFaultdetail = m_pCall->getElementAsString("faultdetail", 0);
throw AxisException(cFaultdetail);
}
else throw;
}
}
int Calculator::getFaultDetail(char** ppcDetail)
{
return m_pCall->getFaultDetail(ppcDetail);
}
DWORD WINAPI Threaded( LPVOID /* lpData */ )
{
Calculator cal;
for(;;)
{
int result = cal.add(22, 33);
printf("The result is xxxx : %d", result);
printf("\n");
Sleep(1000);
}
}
DWORD WINAPI Threaded1( LPVOID /* lpData */ )
{
Calculator cal1;
for(;;)
{
int result1 = cal1.add(22, 5);
printf("The result is xxxx : %d", result1);
printf("\n");
Sleep(1000);
}
}
void main( void )
{
// A Sample Code for porting existent code of Threaded function
CThread t1(Threaded), t2(Threaded1);
t1.Start();
t2.Start();
SleepEx(15 * 1000, FALSE);
t2.Stop();
t1.Stop();
}