/*++ Function : SEHInitialize Initialize all SEH-related stuff (signals, etc) (no parameters) Return value : TRUE if SEH support initialization succeeded FALSE otherwise --*/ BOOL SEHInitialize (void) { pthread_key_t seh_tls_index; int key_retval; BOOL bRet = FALSE; if (PAL_TRY_LOCAL_SIZE < sizeof(sigjmp_buf)) { ASSERT("PAL_TRY_LOCAL_SIZE does not match sizeof(sigjmp_buf)!\n"); } key_retval = pthread_key_create(&seh_tls_index,NULL); if( 0 != key_retval ) { ERROR("Unable to allocate TLS slot for SEH!\n"); return bRet; } TRACE("SEH TLS index is %d\n", seh_tls_index); pSEHInfo = seh_tls_index; pTopFilter = NULL; pCtrlHandler = NULL; if (0 != SYNCInitializeCriticalSection(&exception_critsec)) { ERROR("Unable to initialize SEH critical section!\n"); if (pthread_key_delete(seh_tls_index) != 0) { ERROR("pthread_key_delete failed ...\n"); } } else { #if HAVE_MACH_EXCEPTIONS if (!SEHInitializeMachExceptions()) { ERROR("SEHInitializeMachExceptions failed!\n"); SEHCleanup(); } #else SEHInitializeSignals(); #endif /* force allocation of TLS data for the main thread, so we don't risk a malloc failure *during* exception handling */ if(!SEHInitThread()) { ERROR("SEHInitThread failed!\n"); SEHCleanup(); } else { bRet = TRUE; } } return bRet; }
/*++ Function : MsgBoxInitialize Initialize the critical sections. Return value: TRUE if initialize succeeded FALSE otherwise --*/ BOOL MsgBoxInitialize( void ) { TRACE( "Initialising the critical section.\n" ); if (0 != SYNCInitializeCriticalSection( &msgbox_critsec )) { ERROR("Could not initialize MsgBox critical section!\n"); return FALSE; } return TRUE; }
/*++ Function: PAL_Initialize Abstract: This function is the first function of the PAL to be called. Internal structure initialization is done here. It could be called several time by the same process, a reference count is kept. Return: 0 if successful -1 if it failed --*/ int PALAPI PAL_Initialize( int argc, char *argv[]) { LPWSTR command_line = NULL; LPWSTR exe_path = NULL; int retval = -1; /* the first ENTRY within the first call to PAL_Initialize is a special case, since debug channels are not initialized yet. So in that case the ENTRY will be called after the DBG channels initialization */ ENTRY("PAL_Initialize(argc = %d argv = %p)\n", argc, argv); /*Firstly initiate a temporary lastError storage */ StartupLastError = 0; if(NULL == init_critsec) { PCRITICAL_SECTION temp_critsec; temp_critsec = malloc(sizeof(CRITICAL_SECTION)); if(NULL == temp_critsec) { /* note that these macros probably won't output anything, since the debug channels haven't been initialized yet */ ERROR("couldn't allocate critical section!\n"); LOGEXIT("PAL_Initialize returns %d.\n",-1); return -1; } if (0 != SYNCInitializeCriticalSection(temp_critsec)) { ERROR("couldn't initialize critical section!\n"); free(temp_critsec); LOGEXIT("PAL_Initialize returns %d.\n",-1); return -1; } if(NULL != InterlockedCompareExchangePointer((LPVOID *)&init_critsec, temp_critsec, NULL)) { /* another thread got in before us! shouldn't happen, if the PAL isn't initialized there shouldn't be any other threads */ WARN("Another thread initialized the critical section\n"); DeleteCriticalSection(temp_critsec); free(temp_critsec); } } SYNCEnterCriticalSection(init_critsec, TRUE); if(init_count==0) { // Set our pid. gPID = getpid(); // Initialize the Misc TLS Index and the environment. if (FALSE == MiscInitialize()) { goto done; } // Initialize debug channel settings before anything else. // This depends on the environment, so it must come after // MiscInitialize. if (FALSE == DBG_init_channels()) { goto done; } #if _DEBUG // Verify that our page size is what we think it is. If it's // different, we can't run. if (PAGE_SIZE != getpagesize()) { ASSERT("PAGE_SIZE is incorrect for this system!\n" "Change include/pal/virtual.h and clr/src/inc/stdmacros.h " "to reflect the correct page size of %d.\n", getpagesize()); } #endif // _DEBUG /* Output the ENTRY here, since it doesn't work before initializing debug channels */ ENTRY("PAL_Initialize(argc = %d argv = %p)\n", argc, argv); if(argc<1 || argv==NULL) { ERROR("First-time initialization attempted with bad parameters!\n"); goto done; } if (!INIT_IncreaseDescriptorLimit()) { ERROR("Unable to increase the file descriptor limit!\n"); // We can continue if this fails; we'll just have problems if // we use large numbers of threads or have many open files. } if( !CODEPAGEInit() ) { ERROR( "Unable to initialize the locks or the codepage.\n" ); goto done; } #if defined(__ppc__) { int mib[2]; size_t len; /* Determine the processor's cache line size, for FlushInstructionCache */ mib[0] = CTL_HW; mib[1] = HW_CACHELINE; len = sizeof(CacheLineSize); if (sysctl(mib, 2, &CacheLineSize, &len, NULL, 0) == -1) { goto done; } } #endif //__ppc__ /* Create user's configuration directory if*/ if(FALSE == INIT_InitPalConfigDir()) { ERROR("Unable to setup PAL configuration directory!\n"); goto CLEANUP0; } /* initialize the shared memory infrastructure */ if(!SHMInitialize()) { ERROR("Shared memory initialization failed!\n"); INIT_RemovePalConfigDir(); goto CLEANUP0; } /* initialize handle manager */ if(!HMGRInitHandleManager()) { ERROR("Handle manager initialization failed!\n"); goto CLEANUP1; } /* build the command line */ command_line=INIT_FormatCommandLine(argc,argv); /* find out the application's full path */ exe_path=INIT_FindEXEPath(argv[0]); if(NULL == command_line || NULL == exe_path) { ERROR("Failed to process command-line parameters!\n"); goto CLEANUP2; } /* Initialize the mutex critical sections. */ if (FALSE == MutexInitialize()) { ERROR("Failed to initialize mutex support!\n"); goto CLEANUP2; } /* initialize structure for the inital process */ if (FALSE == PROCCreateInitialProcess(command_line, exe_path) ) { ERROR("Unable to Create the initial process\n"); goto CLEANUP4; } /* initialize structured exception handling stuff (signals, etc) */ if (FALSE == SEHInitialize()) { ERROR("Unable to initialize SEH support\n"); goto CLEANUP5; } /* Initialize the File mapping critical section. */ if (FALSE == MAPInitialize()) { ERROR("Unable to initialize file mapping support\n"); goto CLEANUP6; } /* intialize the strtok function */ if(!StrtokInitialize()) { ERROR("Unable to initialize the strtok function\n"); goto CLEANUP7; } /* initialize module manager */ if(!LOADInitializeModules(exe_path)) { ERROR("Unable to initialize module manager\n"); goto CLEANUP8; } /* Initialize the Virtual* functions. */ if (FALSE == VIRTUALInitialize()) { ERROR("Unable to initialize virtual memory support\n"); goto CLEANUP10; } /* initialize the socket worker thread */ if(!SOCKInitWinSock()) { ERROR("Unable to initialize socket worker thread\n"); goto CLEANUP12; } /* create file objects for standard handles */ if(!FILEInitStdHandles()) { ERROR("Unable to initialize standard file handles\n"); goto CLEANUP13; } /* Initialize the MsgBox functions. */ if (FALSE == MsgBoxInitialize()) { ERROR("Unable to initialize MsgBox management\n"); goto CLEANUP14; } if ( !CRTInitStdStreams() ) { ERROR("Unable to initialize CRT standard streams\n"); goto CLEANUP15; } TRACE("First-time PAL initialization complete.\n"); init_count++; /* Set LastError to a non-good value - functions within the PAL startup may set lasterror to a nonzero value. */ SetLastError(NO_ERROR); retval = 0; } else { init_count++; TRACE("Initialization count increases to %d\n", init_count); retval = 0; } goto done; CLEANUP15: MsgBoxCleanup(); CLEANUP14: FILECleanupStdHandles(); CLEANUP13: SOCKTerminateWinSock(); CLEANUP12: VIRTUALCleanup(); CLEANUP10: LOADFreeModules(TRUE); CLEANUP8: StrtokCleanup(); CLEANUP7: MAPCleanup(); CLEANUP6: SEHCleanup(); CLEANUP5: PROCCleanupInitialProcess(); CLEANUP4: FMTMSG_FormatMessageCleanUp(); MutexCleanup(); CLEANUP2: free(command_line); free(exe_path); HMGRStopHandleManager(); CLEANUP1: SHMCleanup(); INIT_RemovePalConfigDir(); CLEANUP0: CODEPAGECleanup(); ERROR("PAL_Initialize failed\n"); done: SYNCLeaveCriticalSection(init_critsec, TRUE); LOGEXIT("PAL_Initialize returns int %d\n", retval); return retval; }