1. Default operations 2. Declaring a stack size 3. Redirecting the context allocation to something that takes arguments.
The last one may seem like overkill, we could have easily not substituted anything and had the caller entry point cast the ThreadContext to the ArgumentContext and extract any arguments, but then you wouldn't have a live example!
/* CoreLinux++ Copyright (C) 2000 CoreLinux Consortium The CoreLinux++ Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The CoreLinux++ Library Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <Common.hpp> #include <Thread.hpp> #include <ArgumentContext.hpp> using namespace corelinux; #include <iostream> #include <exception> // // In module function prototypes // int main( void ); // // General Functions // void handleAssertion( AssertionCref ); void handleException( ExceptionCref ); // // Thread entry point declarations // Int threadTest( ThreadContextPtr ); Int argumentTest( IntCref ); // // Global data // const int STACKSIZE(4096); // Thread stack size const ThreadIdentifier badThread(-1); // Error identifier // // Main entry point // int main( void ) { cout << endl; // // Practice graceful exception management // try { // // Our first example is a simple default thing. // // Setup the context with default stack and // handlers ThreadContext aSimpleContext(threadTest); cout << "Starting default context thread" << endl; // // Start the thread and wait for return // ThreadIdentifier aThreadld( Thread::startThread(aSimpleContext) ); if( aThreadld != badThread ) { Int aRc( Thread::waitForThread(aThreadld) ); cout << "Thread return code = " << aRc << endl; } else { cout << "Thread error!" << endl; } cout << endl; // // Now we try one with a smaller stack // ThreadContext aStackChangedContext(threadTest,STACKSIZE); cout << "Starting restacked context thread" << endl; aThreadld = Thread::startThread(aStackChangedContext); if( aThreadld != badThread ) { Int aRc( Thread::waitForThread(aThreadld) ); cout << "Thread return code = " << aRc << endl; } else { cout << "Thread error!" << endl; } cout << endl; // // Ok, now for the good stuff. We redirect the // context factory methods in the class so that // we provide a different context. We also set // the threadframe to invoke the call as declared // // // Provide holders for the sets // ArgumentContext aArgContext(argumentTest,5); cout << "Starting argument context thread" << endl; aThreadld = Thread::startThread(aArgContext); if( aThreadld != badThread ) { Int aRc( Thread::waitForThread(aThreadld) ); cout << "Thread return code = " << aRc << endl; } else { cout << "Thread error!" << endl; } cout << endl; // We are clean and return the settings to the // originals Thread::dump(); } catch( AssertionRef aAssert ) { handleAssertion(aAssert); } catch( ExceptionRef aException ) { handleException(aException); } catch( std::exception & e ) { cerr << e.what() << endl; } catch( ... ) { cerr << "Unknown exception." << endl; } return 0; } // // Child thread implementation // Int threadTest( ThreadContextPtr aContextPtr ) { Int returnCode(0); try { cout << "In Child!" << endl; cout << "My identifier is " << aContextPtr->getIdentifier().getScalar() << endl; } catch( ... ) { cerr << "Thread bailing out with exception" << endl; throw; } return returnCode; } // // Argument test thread implementation // Int argumentTest( IntCref aArgument ) { cout << "Argument thread has arg value = " << aArgument << endl; return 0; } // // Error handlers // void handleAssertion( AssertionCref aAssert ) { cerr << aAssert.getFile() << ":" << aAssert.getLine() << ":" << "Assertion: "; if( aAssert.getType() == Assertion::NEVERGETHERE ) { cerr << "NEVER_GET_HERE"; } else { if( aAssert.getType() == Assertion::REQUIRE ) { cerr << "REQUIRE"; } else if( aAssert.getType() == Assertion::ENSURE ) { cerr << "ENSURE"; } else if( aAssert.getType() == Assertion::CHECK ) { cerr << "CHECK"; } else { cerr << "ASSERT"; } cerr << "( " << aAssert.getWhy() << " )"; } cerr << endl; } void handleException( ExceptionCref aExcp ) { cerr << aExcp.getFile() << ":" << aExcp.getLine() << ":" << "Exception: " << aExcp.getWhy() << endl; } /* Common rcs information do not modify $Author: prudhomm $ $Revision: 1.4 $ $Date: 2000/08/31 22:49:02 $ $Locker: $ */