genericopenlibs/cstdlib/TSTLIB/CTHREAD.CPP
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/genericopenlibs/cstdlib/TSTLIB/CTHREAD.CPP	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,177 @@
+// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// C routines for creating EPOC32 threads
+// 
+//
+
+#include <e32std.h>
+#include <estlib.h>		/* for SpawnPosixServerThread */
+#include <unistd.h>
+#include <stdio.h>		/* for popen3 */
+#include <stdlib.h>		/* for mbstowcs */
+#include "CTEST.H"
+#include <sys/errno.h>		/* for errno */
+#include <sys/wait.h>
+
+typedef void (*FUNC)();
+
+struct cthread 
+{
+	RThread iThread;
+	RProcess iProcess;
+	TRequestStatus iStatus;
+	int pid;
+};
+
+TInt threadhelper (TAny* aFn)
+	{
+	CTrapCleanup::New();
+	FUNC f=(FUNC)aFn;
+	(*f)();
+	return 0;
+	}
+
+#if defined(__WINS__)
+
+IMPORT_C void NewProcessId();		// WINS bodges for multiple "processes"
+IMPORT_C void NextProcessFn(TAny*);	
+
+TInt processhelper (TAny* aFn)
+	{
+	// Do the MCRT0.OBJ things straight away
+	NewProcessId();
+	SpawnPosixServerThread();
+	char wd[80];
+	getcwd(wd, sizeof(wd));		// connect to CPosixServer
+	return threadhelper(aFn);
+	}
+
+#endif //__WINS__
+
+
+extern "C" {
+
+EXPORT_C int start_posix_server()
+	{
+	start_redirection_server();
+	return SpawnPosixServerThread();
+	}
+
+EXPORT_C void* create_thread(void (*aFn)(), char* aName)
+	{
+#ifdef _UNICODE
+	TPtrC8 ptr((TText8*)aName);
+	TBuf<80> name;
+	name.Copy(ptr);
+#else
+	TPtrC8 name((TText8*)aName);
+#endif /* _UNICODE */
+	struct cthread* t = new cthread;
+	// 16k stack, share parent's heap
+	TInt err=t->iThread.Create(name, threadhelper, 0x4000, NULL, (TAny*)aFn);
+	t->iThread.Logon(t->iStatus);
+	if (err!= KErrNone)
+		return 0;
+	return (void*)t;
+	}
+
+EXPORT_C void start_thread(void* aThread)
+	{
+	struct cthread* t=REINTERPRET_CAST(struct cthread*,aThread);
+	t->iThread.Resume();
+	}
+
+EXPORT_C int wait_for_thread(void* aThread)
+	{
+	struct cthread* t=REINTERPRET_CAST(struct cthread*,aThread);
+	User::WaitForRequest(t->iStatus);
+	int ret=t->iThread.ExitReason();
+	t->iThread.Close();
+	delete t;
+	return ret;
+	}
+
+EXPORT_C void* create_process(void (*aFn)(), char* aName, char* mode, int fids[3])
+	{
+#ifdef _UNICODE
+	TPtrC8 ptr((TText8*)aName);
+	TBuf<80> name;
+	name.Copy(ptr);
+#else
+	TPtrC8 name((TText8*)aName);
+#endif /* _UNICODE */
+	struct cthread* t = new cthread;
+	TFileName this_exe = t->iProcess.FileName();
+	TBuf<256> cmd;
+	cmd.Format(_L("%S %S"),&this_exe,&name);
+	cmd.ZeroTerminate();
+
+#ifdef _UNICODE
+	wchar_t wmode[MAXPATHLEN+1];
+	mbstowcs(wmode, mode, MAXPATHLEN);
+	t->pid=wpopen3((const wchar_t*)cmd.Ptr(), wmode, 0, fids);
+#else
+	t->pid=popen3((const char*)cmd.Ptr(), mode, 0, fids);
+#endif
+	if (t->pid < 0)
+		return 0;
+	User::After(1000000); // 1 Second
+	return (void*)t;
+	}
+
+EXPORT_C void start_process(void* /*aProcess*/)
+	{
+	// too late, it's already running!
+	}
+
+EXPORT_C int wait_for_process(void* aProcess)
+	{
+	struct cthread* t=REINTERPRET_CAST(struct cthread*,aProcess);
+	int exit=-1;
+	int pid=waitpid(t->pid, &exit, 0);
+	if (pid<0)
+		return errno;
+	return exit;
+	}
+
+EXPORT_C int wait_for_process_id(void* aProcess, int procid, int opt, int* status)
+	{
+	// added function to enable calling of waitpid with specific parameters
+	int pid=waitpid(procid, status, opt);
+	return pid;
+	}
+	
+EXPORT_C int get_proc_id(void* aProcess)
+	{
+	// return the pid of a process
+	struct cthread* t=REINTERPRET_CAST(struct cthread*,aProcess);
+	return t->pid;
+	}
+
+// Testing the dodgy asynchronous form of select
+
+EXPORT_C int async_ioctl(int aFid, int aCmd, void* aParam, int* status)
+	{
+	TRequestStatus& theStatus = *(TRequestStatus*)status;
+	return ioctl(aFid,aCmd,aParam,theStatus);
+	}
+
+EXPORT_C int async_ioctl_completion(int aFid, int aCmd, void* aParam, int* status)
+	{
+	TRequestStatus& theStatus = *(TRequestStatus*)status;
+	User::WaitForRequest(theStatus);
+	return ioctl_complete(aFid,aCmd,aParam,theStatus);
+	}
+
+} // extern "C"