os/ossrv/genericopenlibs/cstdlib/TSTLIB/CTHREAD.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // C routines for creating EPOC32 threads
    15 // 
    16 //
    17 
    18 #include <e32std.h>
    19 #include <estlib.h>		/* for SpawnPosixServerThread */
    20 #include <unistd.h>
    21 #include <stdio.h>		/* for popen3 */
    22 #include <stdlib.h>		/* for mbstowcs */
    23 #include "CTEST.H"
    24 #include <sys/errno.h>		/* for errno */
    25 #include <sys/wait.h>
    26 
    27 typedef void (*FUNC)();
    28 
    29 struct cthread 
    30 {
    31 	RThread iThread;
    32 	RProcess iProcess;
    33 	TRequestStatus iStatus;
    34 	int pid;
    35 };
    36 
    37 TInt threadhelper (TAny* aFn)
    38 	{
    39 	CTrapCleanup::New();
    40 	FUNC f=(FUNC)aFn;
    41 	(*f)();
    42 	return 0;
    43 	}
    44 
    45 #if defined(__WINS__)
    46 
    47 IMPORT_C void NewProcessId();		// WINS bodges for multiple "processes"
    48 IMPORT_C void NextProcessFn(TAny*);	
    49 
    50 TInt processhelper (TAny* aFn)
    51 	{
    52 	// Do the MCRT0.OBJ things straight away
    53 	NewProcessId();
    54 	SpawnPosixServerThread();
    55 	char wd[80];
    56 	getcwd(wd, sizeof(wd));		// connect to CPosixServer
    57 	return threadhelper(aFn);
    58 	}
    59 
    60 #endif //__WINS__
    61 
    62 
    63 extern "C" {
    64 
    65 EXPORT_C int start_posix_server()
    66 	{
    67 	start_redirection_server();
    68 	return SpawnPosixServerThread();
    69 	}
    70 
    71 EXPORT_C void* create_thread(void (*aFn)(), char* aName)
    72 	{
    73 #ifdef _UNICODE
    74 	TPtrC8 ptr((TText8*)aName);
    75 	TBuf<80> name;
    76 	name.Copy(ptr);
    77 #else
    78 	TPtrC8 name((TText8*)aName);
    79 #endif /* _UNICODE */
    80 	struct cthread* t = new cthread;
    81 	// 16k stack, share parent's heap
    82 	TInt err=t->iThread.Create(name, threadhelper, 0x4000, NULL, (TAny*)aFn);
    83 	t->iThread.Logon(t->iStatus);
    84 	if (err!= KErrNone)
    85 		return 0;
    86 	return (void*)t;
    87 	}
    88 
    89 EXPORT_C void start_thread(void* aThread)
    90 	{
    91 	struct cthread* t=REINTERPRET_CAST(struct cthread*,aThread);
    92 	t->iThread.Resume();
    93 	}
    94 
    95 EXPORT_C int wait_for_thread(void* aThread)
    96 	{
    97 	struct cthread* t=REINTERPRET_CAST(struct cthread*,aThread);
    98 	User::WaitForRequest(t->iStatus);
    99 	int ret=t->iThread.ExitReason();
   100 	t->iThread.Close();
   101 	delete t;
   102 	return ret;
   103 	}
   104 
   105 EXPORT_C void* create_process(void (*aFn)(), char* aName, char* mode, int fids[3])
   106 	{
   107 #ifdef _UNICODE
   108 	TPtrC8 ptr((TText8*)aName);
   109 	TBuf<80> name;
   110 	name.Copy(ptr);
   111 #else
   112 	TPtrC8 name((TText8*)aName);
   113 #endif /* _UNICODE */
   114 	struct cthread* t = new cthread;
   115 	TFileName this_exe = t->iProcess.FileName();
   116 	TBuf<256> cmd;
   117 	cmd.Format(_L("%S %S"),&this_exe,&name);
   118 	cmd.ZeroTerminate();
   119 
   120 #ifdef _UNICODE
   121 	wchar_t wmode[MAXPATHLEN+1];
   122 	mbstowcs(wmode, mode, MAXPATHLEN);
   123 	t->pid=wpopen3((const wchar_t*)cmd.Ptr(), wmode, 0, fids);
   124 #else
   125 	t->pid=popen3((const char*)cmd.Ptr(), mode, 0, fids);
   126 #endif
   127 	if (t->pid < 0)
   128 		return 0;
   129 	User::After(1000000); // 1 Second
   130 	return (void*)t;
   131 	}
   132 
   133 EXPORT_C void start_process(void* /*aProcess*/)
   134 	{
   135 	// too late, it's already running!
   136 	}
   137 
   138 EXPORT_C int wait_for_process(void* aProcess)
   139 	{
   140 	struct cthread* t=REINTERPRET_CAST(struct cthread*,aProcess);
   141 	int exit=-1;
   142 	int pid=waitpid(t->pid, &exit, 0);
   143 	if (pid<0)
   144 		return errno;
   145 	return exit;
   146 	}
   147 
   148 EXPORT_C int wait_for_process_id(void* aProcess, int procid, int opt, int* status)
   149 	{
   150 	// added function to enable calling of waitpid with specific parameters
   151 	int pid=waitpid(procid, status, opt);
   152 	return pid;
   153 	}
   154 	
   155 EXPORT_C int get_proc_id(void* aProcess)
   156 	{
   157 	// return the pid of a process
   158 	struct cthread* t=REINTERPRET_CAST(struct cthread*,aProcess);
   159 	return t->pid;
   160 	}
   161 
   162 // Testing the dodgy asynchronous form of select
   163 
   164 EXPORT_C int async_ioctl(int aFid, int aCmd, void* aParam, int* status)
   165 	{
   166 	TRequestStatus& theStatus = *(TRequestStatus*)status;
   167 	return ioctl(aFid,aCmd,aParam,theStatus);
   168 	}
   169 
   170 EXPORT_C int async_ioctl_completion(int aFid, int aCmd, void* aParam, int* status)
   171 	{
   172 	TRequestStatus& theStatus = *(TRequestStatus*)status;
   173 	User::WaitForRequest(theStatus);
   174 	return ioctl_complete(aFid,aCmd,aParam,theStatus);
   175 	}
   176 
   177 } // extern "C"