Más contenido relacionado La actualidad más candente (20) Similar a Потоки в перле изнутри (20) Потоки в перле изнутри4. Структура исходников
• Корень:
• sv.h av.h hv.h gv.h perl.h …
• sv.c av.c hv.c gv.c perl.c malloc.c …
• beos/ haiku/ os2/ plan9/ qnx/ win32/ …
• win32/
• perlmain.c
• Makefile
• win32thread.c …
5. pp_sys.c
PP(pp_fork)
{
#ifdef HAS_FORK
dVAR; dSP; dTARGET;
Pid_t childpid;
EXTEND(SP, 1);
PERL_FLUSHALL_FOR_CHILD;
childpid = PerlProc_fork();
if (childpid < 0)
RETSETUNDEF;
if (!childpid) {
GV * const tmpgv = gv_fetchpvs("$", GV_ADD|GV_NOTQUAL, SVt_PV);
if (tmpgv) {
SvREADONLY_off(GvSV(tmpgv));
sv_setiv(GvSV(tmpgv), (IV)PerlProc_getpid());
SvREADONLY_on(GvSV(tmpgv));
}
...
6. win32win32thread.h
#ifndef DONT_USE_CRITICAL_SECTION
/* Critical Sections used instead of mutexes:
lightweight,
* but can't be communicated to child processes, and
can't get
* HANDLE to it for use elsewhere.
*/
typedef CRITICAL_SECTION perl_mutex;
#define MUTEX_INIT(m) InitializeCriticalSection(m)
#define MUTEX_LOCK(m) EnterCriticalSection(m)
#define MUTEX_UNLOCK(m) LeaveCriticalSection(m)
#define MUTEX_DESTROY(m) DeleteCriticalSection(m)
#else
...
7. win32win32thread.h
...
typedef HANDLE perl_mutex;
# define MUTEX_INIT(m)
STMT_START {
if ((*(m) = CreateMutex(NULL,FALSE,NULL)) == NULL)
Perl_croak_nocontext("panic: MUTEX_INIT");
} STMT_END
# define MUTEX_LOCK(m)
STMT_START {
if (WaitForSingleObject(*(m),INFINITE) == WAIT_FAILED)
Perl_croak_nocontext("panic: MUTEX_LOCK");
} STMT_END
# define MUTEX_UNLOCK(m)
STMT_START {
if (ReleaseMutex(*(m)) == 0)
Perl_croak_nocontext("panic: MUTEX_UNLOCK");
} STMT_END
# define MUTEX_DESTROY(m)
STMT_START {
if (CloseHandle(*(m)) == 0)
Perl_croak_nocontext("panic: MUTEX_DESTROY");
} STMT_END
8. win32win32thread.h
#if defined(USE_RTL_THREAD_API) && !defined(_MSC_VER)
#define JOIN(t, avp)
STMT_START {
if ((WaitForSingleObject((t)->self,INFINITE) == WAIT_FAILED)
|| (GetExitCodeThread((t)->self,(LPDWORD)(avp)) == 0)
|| (CloseHandle((t)->self) == 0))
Perl_croak_nocontext("panic: JOIN");
*avp = (AV *)((t)->i.retv);
} STMT_END
#else /* !USE_RTL_THREAD_API || _MSC_VER */
#define JOIN(t, avp)
STMT_START {
if ((WaitForSingleObject((t)->self,INFINITE) == WAIT_FAILED)
|| (GetExitCodeThread((t)->self,(LPDWORD)(avp)) == 0)
|| (CloseHandle((t)->self) == 0))
Perl_croak_nocontext("panic: JOIN");
} STMT_END
#endif /* !USE_RTL_THREAD_API || _MSC_VER */
#define YIELD Sleep(0)
9. win32perlhost.h
int
PerlProcFork(struct IPerlProc* piPerl)
{
dTHX;
#ifdef USE_ITHREADS
DWORD id;
HANDLE handle;
CPerlHost *h;
if (w32_num_pseudo_children >= MAXIMUM_WAIT_OBJECTS) {
errno = EAGAIN;
return -1;
}
h = new CPerlHost(*(CPerlHost*)w32_internal_host);
PerlInterpreter *new_perl = perl_clone_using((PerlInterpreter*)aTHX,
CLONEf_COPY_STACKS,
h->m_pHostperlMem,
h->m_pHostperlMemShared,
h->m_pHostperlMemParse,
h->m_pHostperlEnv,
h->m_pHostperlStdIO,
h->m_pHostperlLIO,
h->m_pHostperlDir,
h->m_pHostperlSock,
h->m_pHostperlProc
);
10. win32perlhost.h
new_perl->Isys_intern.internal_host = h;
h->host_perl = new_perl;
# ifdef PERL_SYNC_FORK
id = win32_start_child((LPVOID)new_perl);
PERL_SET_THX(aTHX);
# else
if (w32_message_hwnd == INVALID_HANDLE_VALUE)
w32_message_hwnd = win32_create_message_window();
new_perl->Isys_intern.message_hwnd = w32_message_hwnd;
w32_pseudo_child_message_hwnds[w32_num_pseudo_children] =
(w32_message_hwnd == NULL) ? (HWND)NULL : (HWND)INVALID_HANDLE_VALUE;
# ifdef USE_RTL_THREAD_API
handle = (HANDLE)_beginthreadex((void*)NULL, 0, win32_start_child,
(void*)new_perl, 0, (unsigned*)&id);
# else
handle = CreateThread(NULL, 0, win32_start_child,
(LPVOID)new_perl, 0, &id);
# endif
11. win32perlhost.h
PERL_SET_THX(aTHX); /* XXX perl_clone*() set TLS */
if (!handle) {
errno = EAGAIN;
return -1;
}
if (IsWin95()) {
int pid = (int)id;
if (pid < 0)
id = -pid;
}
w32_pseudo_child_handles[w32_num_pseudo_children] = handle;
w32_pseudo_child_pids[w32_num_pseudo_children] = id;
++w32_num_pseudo_children;
# endif
return -(int)id;
#else
Perl_croak(aTHX_ "fork() not implemented!n");
return -1;
#endif /* USE_ITHREADS */
12. win32perlhost.h
CPerlHost::CPerlHost(CPerlHost& host)
{
/* Construct a host from another host */
InterlockedIncrement(&num_hosts);
m_pVMem = new VMem();
m_pVMemShared = host.GetMemShared();
m_pVMemParse = host.GetMemParse();
/* duplicate directory info */
m_pvDir = new VDir(0);
m_pvDir->Init(host.GetDir(), m_pVMem);
13. win32perlhost.h
CopyMemory(&m_hostperlMem, &perlMem, sizeof(perlMem));
CopyMemory(&m_hostperlMemShared, &perlMemShared,
sizeof(perlMemShared));
CopyMemory(&m_hostperlMemParse, &perlMemParse,
sizeof(perlMemParse));
CopyMemory(&m_hostperlEnv, &perlEnv, sizeof(perlEnv));
CopyMemory(&m_hostperlStdIO, &perlStdIO,
sizeof(perlStdIO));
CopyMemory(&m_hostperlLIO, &perlLIO, sizeof(perlLIO));
CopyMemory(&m_hostperlDir, &perlDir, sizeof(perlDir));
CopyMemory(&m_hostperlSock, &perlSock, sizeof(perlSock));
CopyMemory(&m_hostperlProc, &perlProc, sizeof(perlProc));
...