예제 #1
0
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	switch (fdwReason)
	{
		case DLL_PROCESS_ATTACH:

            if (!InitProcess())
                return FALSE;
            break;
		case DLL_THREAD_ATTACH:

            if (!InitThread())
                return FALSE;
            break;

		case DLL_THREAD_DETACH:

			if (!DetachThread())
				return FALSE;
			break;

		case DLL_PROCESS_DETACH:

			DetachProcess();
			break;

		default:
			assert(0 && "DllMain(): Reason for calling DLL Main is unknown");
			return FALSE;
	}

	return TRUE;
}
예제 #2
0
//
// Driver must call this first, once, before doing any other
// compiler operations.
//
int ShInitialize()
{
    if (!InitProcess())
        return 0;

    return 1;
}
예제 #3
0
//
// Driver must call this first, once, before doing any other compiler operations.
// Subsequent calls to this function are no-op.
//
bool ShInitialize()
{
    if (!isInitialized)
    {
        isInitialized = InitProcess();
    }
    return isInitialized;
}
예제 #4
0
static void
WalSendServer_ServicePostgresInit(void)
{
	/* See InitPostgres()... */
    InitProcess();	
	InitBufferPoolBackend();
	InitXLOGAccess();

}
예제 #5
0
/* static */
nsresult
nsMIMEInfoBase::LaunchWithIProcess(nsIFile* aApp, const nsString& aArg)
{
  nsresult rv;
  nsCOMPtr<nsIProcess> process = InitProcess(aApp, &rv);
  if (NS_FAILED(rv))
    return rv;

  const char16_t *string = aArg.get();

  return process->Runw(false, &string, 1);
}
예제 #6
0
BOOL CRelaxReminderDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Add "About..." menu item to system menu.

    // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);            // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
    
    // TODO: Add extra initialization here
    // 只允许运行一个程序实例
    SetProp(m_hWnd, g_szPropName, g_hValue);

    // 初始化成员变量、临界区保护资源、打印模块
    InitProcess();

    // 初始化设置参数
    InitLoadSetting();

    // 初始化提示窗口(必须在加载完参数后执行,由于需要加载窗口语言)
    InitNotifyWindow();

    // 初始化显示
    InitShowFloatingWindow();
    InitShowTrayIcon();

    // 开启1s定时器
    SetTimer(TIMER_HEART_BEAT_1S, 1000, NULL);

    // 自动开始计时
    OnMenuStartWork();
    
    return TRUE;  // return TRUE  unless you set the focus to a control
}
예제 #7
0
//
// ShInitialize() should be called exactly once per process, not per thread.
//
int ShInitialize()
{
    glslang::InitGlobalLock();

    if (! InitProcess())
        return 0;

    if (! PerProcessGPA)
        PerProcessGPA = new TPoolAllocator();

    glslang::TScanContext::fillInKeywordMap();

    return 1;
}
예제 #8
0
int C_DECL Hlsl2Glsl_Initialize(GlobalAllocateFunction alloc, GlobalFreeFunction free, void* user)
{
   TInfoSink infoSink;
   bool ret = true;

   SetGlobalAllocationAllocator(alloc, free, user);
	
   if (!InitProcess())
      return 0;

   // This method should be called once per process. If its called by multiple threads, then 
   // we need to have thread synchronization code around the initialization of per process
   // global pool allocator
   if (!PerProcessGPA)
   {
      TPoolAllocator *builtInPoolAllocator = new TPoolAllocator(true);
      builtInPoolAllocator->push();
      TPoolAllocator* gPoolAllocator = &GlobalPoolAllocator;
      SetGlobalPoolAllocatorPtr(builtInPoolAllocator);

      TSymbolTable symTables[EShLangCount];
      GenerateBuiltInSymbolTable(infoSink, symTables, EShLangCount);

      PerProcessGPA = new TPoolAllocator(true);
      PerProcessGPA->push();
      SetGlobalPoolAllocatorPtr(PerProcessGPA);

      SymbolTables[EShLangVertex].copyTable(symTables[EShLangVertex]);
      SymbolTables[EShLangFragment].copyTable(symTables[EShLangFragment]);

      SetGlobalPoolAllocatorPtr(gPoolAllocator);

      symTables[EShLangVertex].pop();
      symTables[EShLangFragment].pop();

      initializeHLSLSupportLibrary();

      builtInPoolAllocator->popAll();
      delete builtInPoolAllocator;        

   }

   return ret ? 1 : 0;
}
예제 #9
0
//
// Driver must call this first, once, before doing any other
// compiler/linker operations.
//
int ShInitialize()
{
    TInfoSink infoSink;
    bool ret = true;

    if (!InitProcess())
        return 0;

    // This method should be called once per process. If its called by multiple threads, then 
    // we need to have thread synchronization code around the initialization of per process
    // global pool allocator
    if (!PerProcessGPA) { 
        TPoolAllocator *builtInPoolAllocator = new TPoolAllocator(true);
        builtInPoolAllocator->push();
        TPoolAllocator* gPoolAllocator = &GlobalPoolAllocator;
        SetGlobalPoolAllocatorPtr(builtInPoolAllocator);

        TSymbolTable symTables[EShLangCount];
        GenerateBuiltInSymbolTable(0, infoSink, symTables);

        PerProcessGPA = new TPoolAllocator(true);
        PerProcessGPA->push();
        SetGlobalPoolAllocatorPtr(PerProcessGPA);

        SymbolTables[EShLangVertex].copyTable(symTables[EShLangVertex]);
        SymbolTables[EShLangFragment].copyTable(symTables[EShLangFragment]);

        SetGlobalPoolAllocatorPtr(gPoolAllocator);

        symTables[EShLangVertex].pop();
        symTables[EShLangFragment].pop();

        builtInPoolAllocator->popAll();
        delete builtInPoolAllocator;        

    }

    return ret ? 1 : 0;
}
예제 #10
0
int C_DECL Hlsl2Glsl_Initialize()
{
   TInfoSink infoSink;

   if (!InitProcess())
      return 0;

   if (!PerProcessGPA)
   {
      TPoolAllocator *builtInPoolAllocator = new TPoolAllocator();
      builtInPoolAllocator->push();
      TPoolAllocator* gPoolAllocator = &GlobalPoolAllocator;
      SetGlobalPoolAllocatorPtr(builtInPoolAllocator);

      TSymbolTable symTables[EShLangCount];
      GenerateBuiltInSymbolTable(infoSink, symTables, EShLangCount);

      PerProcessGPA = new TPoolAllocator();
      PerProcessGPA->push();
      SetGlobalPoolAllocatorPtr(PerProcessGPA);

      SymbolTables[EShLangVertex].copyTable(symTables[EShLangVertex]);
      SymbolTables[EShLangFragment].copyTable(symTables[EShLangFragment]);

      SetGlobalPoolAllocatorPtr(gPoolAllocator);

      symTables[EShLangVertex].pop();
      symTables[EShLangFragment].pop();

      builtInPoolAllocator->popAll();
      delete builtInPoolAllocator;        

   }

   return 1;
}
예제 #11
0
파일: iotjs.cpp 프로젝트: no-problemo/iotjs
static JObject* InitModules() {
  InitModuleList();
  return InitProcess();
}
예제 #12
0
파일: gamemain.cpp 프로젝트: Taka03/Nolfeus
//================================================
//メインループ
//================================================
void Luna::Main(long ArgNum, char *pArgStr[])
{

	//----------------------------------------
	//全システムの開始
	//----------------------------------------	
	if(Luna::Start() )
	{
		//--------------------------------
		//初期化処理
		//--------------------------------
		InitProcess();
		
		//LunaInput::GetMouseData(&camera.Mouse);
		//LunaInput::GetMouseData(&camera.MouseOld);
		
		//--------------------------------
		//ゲーム用ループ
		//--------------------------------
		while(Luna::WaitForMsgLoop() )
		{
			
			/*画面クリア*/
			Luna3D::Clear(D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, COLOR_BLACK, 1.0f);
			
			//Luna3D::Clear(D3DCLEAR_TARGET, COLOR_WHITE);
			
			/*デバッグ画面クリア*/
		//	LunaDebug::Clear();
			
			switch(g_GameMode)
			{
				case SCENE_INITIALIZE:
				{
					Initialize();
					break;
				}
				
				case SCENE_LOGO:
				{
					//DrawLogo();
					break;
				}
				
				case SCENE_TITLE:
				{
					DrawTitle();
					break;
				}
				
				case SCENE_CHARSEL:
				{
					DrawCharaSelect();
					break;
				}
				
				case SCENE_MAIN:
				{
					DrawMain();
					break;
				}
				
				case SCENE_OPTION:
				{
					DrawOption();
					break;
				}
				
				case SCENE_TUTOLIAL:
				{
					DrawTutorial();
					break;
				}
				
				case SCENE_PAUSE:
				{
					DrawPause();
					break;
				}
				
				case SCENE_PAUSEEXIT:
				{
					DrawPauseExit();
					break;
				}
				
				case SCENE_ERROR:
				{
					DrawError();
					break;
				}
				
				case SCENE_EXIT:
				{
					DrawExit();
					break;
				}
				
				case SCENE_FADEIN:
				{
					Fadein();
					break;
				}
				
				case SCENE_FADEOUT:
				{
					Fadeout();	
					break;
				}
				
				case SCENE_CONV:
				{
					Conversation();
					break;
				}
				
				case SCENE_GAMECLEAR:
				{
					DrawGameClear();
					break;
				}
				
				case SCENE_GAMEOVER:
				{
					DrawGameOver();
					break;
				}
				
				case SCENE_CONTINUE:
				{
					DrawContinue();
					break;
				}
				
				case SCENE_FINALIZE:
				{
					Finalize();
					break;
				}
				
			}
			
			/*画面更新*/
			Luna3D::Refresh();
			
			/*デバッグ処理*/
		//	Debug();
		}

		/*終了処理*/
		Finalize();
	}
}
예제 #13
0
//-------------------------------------------------
BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID reserved)
{
    HANDLE hMapObject = NULL;   /* handle to file mapping */ 
    BOOL fInit, fIgnore; 
//	ThreadData *pThread;
    switch (reason) { 
 		case DLL_PROCESS_ATTACH: 
 
            /* Create a named file mapping object */ 
			MyInstance =  hModule;
            hMapObject = CreateFileMapping( 
                (HANDLE) 0xFFFFFFFF, /* use paging file    */ 
                NULL,                /* no security attr.  */ 
                PAGE_READWRITE,      /* read/write access  */ 
                0,                   /* size: high 32-bits */ 
                sizeof(SharedMem),   /* size: low 32-bits  */ 
                _TEXT("UniKeyHookSharedMem3.65 Release"));/* name of map object */ 
            if (hMapObject == NULL) 
                return FALSE; 
			
			fInit = (GetLastError() != ERROR_ALREADY_EXISTS);
            /* Get a pointer to the file-mapped shared memory. */ 
 
            pShMem = (SharedMem *) MapViewOfFile( 
				hMapObject,     /* object to map view of    */ 
                FILE_MAP_WRITE, /* read/write access        */ 
                0,              /* high offset:   map from  */ 
                0,              /* low offset:    beginning */ 
                0);             /* default: map entire file */ 
            if (pShMem == NULL) 
                return FALSE; 
			InitProcess();
			if (fInit)
				initDLL();
//			TlsIdx = TlsAlloc();
//			InitThread();
         break; 
 
        /* 
         * The DLL is detaching from a process due to 
         * process termination or a call to FreeLibrary. 
         */ 
/*
		  case DLL_THREAD_ATTACH:
			  InitThread();
			  break;
		  case DLL_THREAD_DETACH:
			  pThread = (ThreadData *)TlsGetValue(TlsIdx);
			  if (pThread != NULL) 
				delete pThread;
			  break;
*/
		case DLL_PROCESS_DETACH: 
 
            /* Unmap shared memory from the process's address space. */ 
 
            fIgnore = UnmapViewOfFile(pShMem); 
 
            /* Close the process's handle to the file-mapping object. */ 
 
            fIgnore = CloseHandle(hMapObject); 
//			TlsFree(TlsIdx);
            break; 
 
        default: 
          break; 
 
  } 
 
  return TRUE; 
  UNREFERENCED_PARAMETER(hModule); 
  UNREFERENCED_PARAMETER(reserved); 
 
}
예제 #14
0
/* --------------------------------
 * InitPostgres
 *		Initialize POSTGRES.
 *
 * Note:
 *		Be very careful with the order of calls in the InitPostgres function.
 * --------------------------------
 */
void
InitPostgres(const char *dbname, const char *username)
{
	bool		bootstrap = IsBootstrapProcessingMode();

	/*
	 * Set up the global variables holding database id and path.
	 *
	 * We take a shortcut in the bootstrap case, otherwise we have to look up
	 * the db name in pg_database.
	 */
	if (bootstrap)
	{
		MyDatabaseId = TemplateDbOid;
		SetDatabasePath(GetDatabasePath(MyDatabaseId));
	}
	else
	{
		char	   *fullpath,
					datpath[MAXPGPATH];

		/*
		 * Formerly we validated DataDir here, but now that's done
		 * earlier.
		 */

		/*
		 * Find oid and path of the database we're about to open. Since
		 * we're not yet up and running we have to use the hackish
		 * GetRawDatabaseInfo.
		 */
		GetRawDatabaseInfo(dbname, &MyDatabaseId, datpath);

		if (!OidIsValid(MyDatabaseId))
			ereport(FATAL,
					(errcode(ERRCODE_UNDEFINED_DATABASE),
					 errmsg("database \"%s\" does not exist",
							dbname)));

		fullpath = GetDatabasePath(MyDatabaseId);

		/* Verify the database path */

		if (access(fullpath, F_OK) == -1)
		{
			if (errno == ENOENT)
				ereport(FATAL,
						(errcode(ERRCODE_UNDEFINED_DATABASE),
						 errmsg("database \"%s\" does not exist",
								dbname),
				errdetail("The database subdirectory \"%s\" is missing.",
						  fullpath)));
			else
				ereport(FATAL,
						(errcode_for_file_access(),
						 errmsg("could not access directory \"%s\": %m",
								fullpath)));
		}

		ValidatePgVersion(fullpath);

		if (chdir(fullpath) == -1)
			ereport(FATAL,
					(errcode_for_file_access(),
					 errmsg("could not change directory to \"%s\": %m",
							fullpath)));

		SetDatabasePath(fullpath);
	}

	/*
	 * Code after this point assumes we are in the proper directory!
	 */

	/*
	 * Set up my per-backend PGPROC struct in shared memory.	(We need
	 * to know MyDatabaseId before we can do this, since it's entered into
	 * the PGPROC struct.)
	 */
	InitProcess();

	/*
	 * Initialize my entry in the shared-invalidation manager's array of
	 * per-backend data.  (Formerly this came before InitProcess, but now
	 * it must happen after, because it uses MyProc.)  Once I have done
	 * this, I am visible to other backends!
	 *
	 * Sets up MyBackendId, a unique backend identifier.
	 */
	MyBackendId = InvalidBackendId;

	InitBackendSharedInvalidationState();

	if (MyBackendId > MaxBackends || MyBackendId <= 0)
		elog(FATAL, "bad backend id: %d", MyBackendId);

	/*
	 * Initialize the transaction system override state.
	 */
	AmiTransactionOverride(bootstrap);

	/*
	 * Initialize the relation descriptor cache.  This must create at
	 * least the minimum set of "nailed-in" cache entries.	No catalog
	 * access happens here.
	 */
	RelationCacheInitialize();

	/*
	 * Initialize all the system catalog caches.  Note that no catalog
	 * access happens here; we only set up the cache structure.
	 */
	InitCatalogCache();

	/* Initialize portal manager */
	EnablePortalManager();

	/*
	 * Initialize the deferred trigger manager --- must happen before
	 * first transaction start.
	 */
	DeferredTriggerInit();

	/* start a new transaction here before access to db */
	if (!bootstrap)
		StartTransactionCommand();

	/*
	 * It's now possible to do real access to the system catalogs.
	 *
	 * Replace faked-up relcache entries with correct info.
	 */
	RelationCacheInitializePhase2();

	/*
	 * Figure out our postgres user id.  In standalone mode we use a fixed
	 * id, otherwise we figure it out from the authenticated user name.
	 */
	if (bootstrap)
		InitializeSessionUserIdStandalone();
	else if (!IsUnderPostmaster)
	{
		InitializeSessionUserIdStandalone();
		if (!ThereIsAtLeastOneUser())
			ereport(WARNING,
					(errcode(ERRCODE_UNDEFINED_OBJECT),
				  errmsg("no users are defined in this database system"),
					 errhint("You should immediately run CREATE USER \"%s\" WITH SYSID %d CREATEUSER;.",
							 username, BOOTSTRAP_USESYSID)));
	}
	else
	{
		/* normal multiuser case */
		InitializeSessionUserId(username);
	}

	/*
	 * Unless we are bootstrapping, double-check that InitMyDatabaseInfo()
	 * got a correct result.  We can't do this until all the
	 * database-access infrastructure is up.
	 */
	if (!bootstrap)
		ReverifyMyDatabase(dbname);

	/*
	 * Final phase of relation cache startup: write a new cache file if
	 * necessary.  This is done after ReverifyMyDatabase to avoid writing
	 * a cache file into a dead database.
	 */
	RelationCacheInitializePhase3();

	/*
	 * Check a normal user hasn't connected to a superuser reserved slot.
	 * We can't do this till after we've read the user information, and we
	 * must do it inside a transaction since checking superuserness may
	 * require database access.  The superuser check is probably the most
	 * expensive part; don't do it until necessary.
	 */
	if (ReservedBackends > 0 &&
		CountEmptyBackendSlots() < ReservedBackends &&
		!superuser())
		ereport(FATAL,
				(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
				 errmsg("connection limit exceeded for non-superusers")));

	/*
	 * Initialize various default states that can't be set up until we've
	 * selected the active user and done ReverifyMyDatabase.
	 */

	/* set default namespace search path */
	InitializeSearchPath();

	/* initialize client encoding */
	InitializeClientEncoding();

	/*
	 * Now all default states are fully set up.  Report them to client if
	 * appropriate.
	 */
	BeginReportingGUCOptions();

	/*
	 * Set up process-exit callback to do pre-shutdown cleanup.  This
	 * should be last because we want shmem_exit to call this routine
	 * before the exit callbacks that are registered by buffer manager,
	 * lock manager, etc. We need to run this code before we close down
	 * database access!
	 */
	on_shmem_exit(ShutdownPostgres, 0);

	/* close the transaction we started above */
	if (!bootstrap)
		CommitTransactionCommand();
}
예제 #15
0
파일: autovacuum.c 프로젝트: huor/gpdb
/*
 * AutoVacMain
 */
NON_EXEC_STATIC void
AutoVacMain(int argc, char *argv[])
{
    ListCell   *cell;
    List	   *dblist;
    autovac_dbase *db;
    TransactionId xidForceLimit;
    bool		for_xid_wrap;
    sigjmp_buf	local_sigjmp_buf;

    /* we are a postmaster subprocess now */
    IsUnderPostmaster = true;
    am_autovacuum = true;

    /* MPP-4990: Autovacuum always runs as utility-mode */
    Gp_role = GP_ROLE_UTILITY;

    /* reset MyProcPid */
    MyProcPid = getpid();

    /* record Start Time for logging */
    MyStartTime = time(NULL);

    /* Identify myself via ps */
    init_ps_display("autovacuum process", "", "", "");

    SetProcessingMode(InitProcessing);

    /*
     * If possible, make this process a group leader, so that the postmaster
     * can signal any child processes too.  (autovacuum probably never has
     * any child processes, but for consistency we make all postmaster
     * child processes do this.)
     */
#ifdef HAVE_SETSID
    if (setsid() < 0)
        elog(FATAL, "setsid() failed: %m");
#endif

    /*
     * Set up signal handlers.	We operate on databases much like a regular
     * backend, so we use the same signal handling.  See equivalent code in
     * tcop/postgres.c.
     *
     * Currently, we don't pay attention to postgresql.conf changes that
     * happen during a single daemon iteration, so we can ignore SIGHUP.
     */
    pqsignal(SIGHUP, SIG_IGN);

    /*
     * SIGINT is used to signal cancelling the current table's vacuum; SIGTERM
     * means abort and exit cleanly, and SIGQUIT means abandon ship.
     */
    pqsignal(SIGINT, StatementCancelHandler);
    pqsignal(SIGTERM, die);
    pqsignal(SIGQUIT, quickdie);
    pqsignal(SIGALRM, handle_sig_alarm);

    pqsignal(SIGPIPE, SIG_IGN);
    pqsignal(SIGUSR1, procsignal_sigusr1_handler);
    /* We don't listen for async notifies */
    pqsignal(SIGUSR2, SIG_IGN);
    pqsignal(SIGFPE, FloatExceptionHandler);
    pqsignal(SIGCHLD, SIG_DFL);

    /* Early initialization */
    BaseInit();

    /*
     * Create a per-backend PGPROC struct in shared memory, except in the
     * EXEC_BACKEND case where this was done in SubPostmasterMain. We must do
     * this before we can use LWLocks (and in the EXEC_BACKEND case we already
     * had to do some stuff with LWLocks).
     */
#ifndef EXEC_BACKEND
    InitProcess();
#endif

    /*
     * If an exception is encountered, processing resumes here.
     *
     * See notes in postgres.c about the design of this coding.
     */
    if (sigsetjmp(local_sigjmp_buf, 1) != 0)
    {
        /* Prevents interrupts while cleaning up */
        HOLD_INTERRUPTS();

        /* Report the error to the server log */
        EmitErrorReport();

        /*
         * We can now go away.	Note that because we called InitProcess, a
         * callback was registered to do ProcKill, which will clean up
         * necessary state.
         */
        proc_exit(0);
    }

    /* We can now handle ereport(ERROR) */
    PG_exception_stack = &local_sigjmp_buf;

    PG_SETMASK(&UnBlockSig);

    /*
     * Force zero_damaged_pages OFF in the autovac process, even if it is set
     * in postgresql.conf.	We don't really want such a dangerous option being
     * applied non-interactively.
     */
    SetConfigOption("zero_damaged_pages", "false", PGC_SUSET, PGC_S_OVERRIDE);

    /* Get a list of databases */
    dblist = autovac_get_database_list();

    /*
     * Determine the oldest datfrozenxid/relfrozenxid that we will allow
     * to pass without forcing a vacuum.  (This limit can be tightened for
     * particular tables, but not loosened.)
     */
    recentXid = ReadNewTransactionId();
    xidForceLimit = recentXid - autovacuum_freeze_max_age;
    /* ensure it's a "normal" XID, else TransactionIdPrecedes misbehaves */
    if (xidForceLimit < FirstNormalTransactionId)
        xidForceLimit -= FirstNormalTransactionId;

    /*
     * Choose a database to connect to.  We pick the database that was least
     * recently auto-vacuumed, or one that needs vacuuming to prevent Xid
     * wraparound-related data loss.  If any db at risk of wraparound is
     * found, we pick the one with oldest datfrozenxid,
     * independently of autovacuum times.
     *
     * Note that a database with no stats entry is not considered, except for
     * Xid wraparound purposes.  The theory is that if no one has ever
     * connected to it since the stats were last initialized, it doesn't need
     * vacuuming.
     *
     * XXX This could be improved if we had more info about whether it needs
     * vacuuming before connecting to it.  Perhaps look through the pgstats
     * data for the database's tables?  One idea is to keep track of the
     * number of new and dead tuples per database in pgstats.  However it
     * isn't clear how to construct a metric that measures that and not cause
     * starvation for less busy databases.
     */
    db = NULL;
    for_xid_wrap = false;
    foreach(cell, dblist)
    {
        autovac_dbase *tmp = lfirst(cell);

        /* Find pgstat entry if any */
        tmp->entry = pgstat_fetch_stat_dbentry(tmp->oid);

        /* Check to see if this one is at risk of wraparound */
        if (TransactionIdPrecedes(tmp->frozenxid, xidForceLimit))
        {
            if (db == NULL ||
                    TransactionIdPrecedes(tmp->frozenxid, db->frozenxid))
                db = tmp;
            for_xid_wrap = true;
            continue;
        }
        else if (for_xid_wrap)
            continue;			/* ignore not-at-risk DBs */

        /*
         * Otherwise, skip a database with no pgstat entry; it means it
         * hasn't seen any activity.
         */
        if (!tmp->entry)
            continue;

        /*
         * Remember the db with oldest autovac time.  (If we are here,
         * both tmp->entry and db->entry must be non-null.)
         */
        if (db == NULL ||
                tmp->entry->last_autovac_time < db->entry->last_autovac_time)
            db = tmp;
    }
예제 #16
0
void init(int argc, char **argv)
{
FILE *fp;
int daemon = FALSE;
int i, ntoken, status, problems;
BOOL debug;
THREAD tid;
char pwd[MAXPATHLEN+1], RunFile[MAXPATHLEN+1];
char *token[MAXTOKEN];
char *myname, *sta, *log, *user, *prefix, *dbspec = NULL;
struct stat statbuf;
struct isp_dascnf dascnf;
LOGIO *lp = NULL;
static char *fid = "init";

    memset(DasCnf, 0, sizeof(struct isp_dascnf));
    MUTEX_INIT(&DasCnf->mutex);

/* Get my name without path prefix (if any) */

    if ((myname = strdup(argv[0])) == NULL) {
        perror(argv[0]);
        exit(1);
    }

    ntoken = util_sparse(myname, token, "./", MAXTOKEN);
    myname = token[ntoken-1];

/* Parse command line for required input and selected overrides */

    sta   = (char *) NULL;
    user  = ISPD_DEF_USER;
    log   = NULL;
    debug = ISPD_DEF_DEBUG;

    for (i = 1; i < argc; i++) {
        if (strncasecmp(argv[i], "sta=", strlen("sta=")) == 0) {
            sta = argv[i] + strlen("sta=");
        } else if (strncasecmp(argv[i], "log=", strlen("log=")) == 0) {
            log = argv[i] + strlen("log=");
        } else if (strncasecmp(argv[i], "db=", strlen("db=")) == 0) {
            dbspec = argv[i] + strlen("db=");
        } else if (strncasecmp(argv[i], "user="******"user="******"user="******"-debug") == 0) {
            debug = TRUE;
        } else if (strcasecmp(argv[i], "-bd") == 0) {
            daemon = TRUE;
        } else if (sta == (char *) NULL) {
            sta = argv[i];
        } else {
            help(myname);
        }
    }

    if (sta == NULL) {
        fprintf(stderr, "%s: system name must be specified\n", myname);
        help(myname);
    }

    if (log == NULL) log = daemon ? DEFAULT_BACKGROUND_LOG : DEFAULT_FOREGROUND_LOG;

    if (!isidlSetGlobalParameters(dbspec, argv[0], &Params->glob)) {
        fprintf(stderr, "%s: isidlSetGlobalParameters: %s\n", argv[0], strerror(errno));
        exit(1);
    }

    sprintf(pwd, "%s/%s/%s", Params->glob.root, sta, ISP_SUBDIR);
    if (chdir(pwd) != 0) {
        fprintf(stderr, "%s: chdir: ", myname);
        perror(pwd);
        exit (1);
    }

    Home    = strdup(Params->glob.root);
    Syscode = strdup(sta);
    prefix  = strdup(sta);

    if (Home == (char *) NULL || Syscode == (char *) NULL || prefix == NULL) {
        perror(myname);
        exit(1);
    }
    Syscode = util_lcase(Syscode);

/* Make sure we can find the various set up files now */

    problems = 0;

    if ((fp = fopen(ISP_RUN_FILE, "r")) == (FILE *) NULL) {
        fprintf(stderr, "%s: fopen: %s/", myname, pwd);
        perror(ISP_RUN_FILE);
        ++problems;
    } else {
        fclose(fp);
    }

    if (problems) exit(1);

/* Load run parameters */

    sprintf(RunFile, "%s/%s", pwd, ISP_RUN_FILE);
    if (!ispLoadRunParam(RunFile, sta, Params, Server)) {
        fprintf(stderr, "%s: problems with parameter file\n", myname);
        exit(1);
    }

/* By insuring that we can stat the output device now, we will later
 * be able to treat open failures as no-media-installed conditions.
 */

    SetOutputMediaType();
    if (OutputMediaType() == ISP_OUTPUT_TAPE && stat(Params->odev, &statbuf) != 0) {
        fprintf(stderr, "%s: can't stat: ", myname);
        perror(Params->odev);
        exit(1);
    }


/* Check for digitizer specific support files */

    if (Params->digitizer == ISP_DAS) {
        if (isp_getcnf(&dascnf) != 0) {
            fprintf(stderr, "%s: fopen: %s/", myname, pwd);
            perror(ISP_CNF_FILE);
            fprintf(stderr, "can't load DAS configuration... set default\n");
            dascnf.flag = ISP_DASCNF_DEF;
            if (isp_setcnf(&dascnf) != 0 || isp_getcnf(&dascnf) != 0) {
                perror("can't load default DAS configuration either!\n");
                ++problems;
            }
        }
    }

    if (problems) exit(1);

/* Set user and group identity */

    utilSetIdentity(user);

/* Go into the background */

    if (daemon && !utilBackGround()) {
        perror("utilBackGround");
        exit(1);
    }

/* Start logging facility */

    util_ucase(prefix);
    if ((lp = InitLogging(myname, log, prefix, debug)) == NULL) {
        perror("InitLogging");
        exit(1);
    }
    ispSetLogParameter(Params, lp);

    LogMsg(LOG_DEBUG, "uid=%d, euid=%d, gid=%d, egid=%d", getuid(), geteuid(), getgid(), getegid());

    if (Params->rt593.present) {
        LogMsg(LOG_INFO, "Configured for RT593 with %d tic delay", Params->rt593.correct);
    }

/* Initialize the message queues and massio buffers */

    InitMsgqs();

/* Initialize the status structure */

    status_init();

/* Start signal handling thread */

    signals_init();

/* Initialize the output device */

    InitMediaOps();

/* Start the ISI thread */

    InitIsi(lp);
    sleep(1);

/* Start the digitizer specific I/O thread */

    if (Params->digitizer == ISP_DAS) {
        InitDasIO();
    } else {
        InitSanIO();
    }
    sleep(1);

/* Start the DAS packet processor thread */

    InitProcess();
    sleep(1);

/* Start the massio buffering thread */

    InitMassio();
    sleep(1);

/* Start the DAS status request thread */

    InitSoh();
    sleep(1);

/* Start the digitizer configuration verification process */

    if (Params->digitizer == ISP_DAS) {
        VerifyDasConfig(0);
    } else {
        VerifySanConfig(0);
    }

/* Start up auxiliary threads, if any */

    if (Params->clock.enabled) {
        set_alarm(ISP_ALARM_AUXCLK);
        InitClock();
    }

    if (Params->baro.enabled) {
        set_alarm(ISP_ALARM_AUX);
        InitBaro();
    }

    if (Params->dpm.enabled) {
        set_alarm(ISP_ALARM_AUX);
        InitDPM();
    }

/* Start up ISP injection service */

    if (Params->inject) isp_inject();

/* Command and control server */

    server_init();

/* iboot watchdog */

    StartIbootWatchdog();

    return;
}
예제 #17
0
void
ContQuerySchedulerMain(int argc, char *argv[])
{
	sigjmp_buf local_sigjmp_buf;
	List *dbs = NIL;

	/* we are a postmaster subprocess now */
	IsUnderPostmaster = true;
	am_cont_scheduler = true;

	/* reset MyProcPid */
	MyProcPid = getpid();
	MyPMChildSlot = AssignPostmasterChildSlot();

	/* record Start Time for logging */
	MyStartTime = time(NULL);

	/* Identify myself via ps */
	init_ps_display("continuous query scheduler process", "", "", "");

	ereport(LOG, (errmsg("continuous query scheduler started")));

	if (PostAuthDelay)
		pg_usleep(PostAuthDelay * 1000000L);

	SetProcessingMode(InitProcessing);

	/*
	 * If possible, make this process a group leader, so that the postmaster
	 * can signal any child processes too. This is only for consistency sake, we
	 * never fork the scheduler process. Instead dynamic bgworkers are used.
	 */
#ifdef HAVE_SETSID
	if (setsid() < 0)
		elog(FATAL, "setsid() failed: %m");
#endif

	/*
	 * Set up signal handlers.  We operate on databases much like a regular
	 * backend, so we use the same signal handling.  See equivalent code in
	 * tcop/postgres.c.
	 */
	pqsignal(SIGHUP, sighup_handler);
	pqsignal(SIGINT, sigint_handler);
	pqsignal(SIGTERM, sigterm_handler);

	pqsignal(SIGQUIT, quickdie);
	InitializeTimeouts(); /* establishes SIGALRM handler */

	pqsignal(SIGPIPE, SIG_IGN);
	pqsignal(SIGUSR1, procsignal_sigusr1_handler);
	pqsignal(SIGUSR2, sigusr2_handler);
	pqsignal(SIGFPE, FloatExceptionHandler);
	pqsignal(SIGCHLD, SIG_DFL);

#define BACKTRACE_SEGFAULTS
#ifdef BACKTRACE_SEGFAULTS
	pqsignal(SIGSEGV, debug_segfault);
#endif

	/* Early initialization */
	BaseInit();

	/*
	 * Create a per-backend PGPROC struct in shared memory, except in the
	 * EXEC_BACKEND case where this was done in SubPostmasterMain. We must do
	 * this before we can use LWLocks (and in the EXEC_BACKEND case we already
	 * had to do some stuff with LWLocks).
	 */
#ifndef EXEC_BACKEND
	InitProcess();
#endif

	InitPostgres(NULL, InvalidOid, NULL, NULL);

	SetProcessingMode(NormalProcessing);

	/*
	 * Create a memory context that we will do all our work in.  We do this so
	 * that we can reset the context during error recovery and thereby avoid
	 * possible memory leaks.
	 */
	ContQuerySchedulerMemCxt = AllocSetContextCreate(TopMemoryContext,
			"ContQuerySchedulerCtx",
			ALLOCSET_DEFAULT_MINSIZE,
			ALLOCSET_DEFAULT_INITSIZE,
			ALLOCSET_DEFAULT_MAXSIZE);
	MemoryContextSwitchTo(ContQuerySchedulerMemCxt);

	/*
	 * If an exception is encountered, processing resumes here.
	 *
	 * This code is a stripped down version of PostgresMain error recovery.
	 */
	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
	{
		/* since not using PG_TRY, must reset error stack by hand */
		error_context_stack = NULL;

		/* Prevents interrupts while cleaning up */
		HOLD_INTERRUPTS();

		/* Forget any pending QueryCancel or timeout request */
		disable_all_timeouts(false);
		QueryCancelPending = false; /* second to avoid race condition */

		/* Report the error to the server log */
		EmitErrorReport();

		/* Abort the current transaction in order to recover */
		AbortCurrentTransaction();

		/*
		 * Now return to normal top-level context and clear ErrorContext for
		 * next time.
		 */
		MemoryContextSwitchTo(ContQuerySchedulerMemCxt);
		FlushErrorState();

		/* Flush any leaked data in the top-level context */
		MemoryContextResetAndDeleteChildren(ContQuerySchedulerMemCxt);

		/* Now we can allow interrupts again */
		RESUME_INTERRUPTS();

		/*
		 * Sleep at least 1 second after any error.  We don't want to be
		 * filling the error logs as fast as we can.
		 */
		pg_usleep(1000000L);
	}
	/* We can now handle ereport(ERROR) */
	PG_exception_stack = &local_sigjmp_buf;

	/* must unblock signals before calling rebuild_database_list */
	PG_SETMASK(&UnBlockSig);

	ContQuerySchedulerShmem->scheduler_pid = MyProcPid;

	dbs = get_database_list();

	/* Loop forever */
	for (;;)
	{
		ListCell *lc;
		int rc;

		foreach(lc, dbs)
		{
			DatabaseEntry *db_entry = lfirst(lc);
			bool found;
			ContQueryProcGroup *grp = hash_search(ContQuerySchedulerShmem->proc_table, &db_entry->oid, HASH_ENTER, &found);

			/* If we don't have an entry for this dboid, initialize a new one and fire off bg procs */
			if (!found)
			{
				grp->db_oid = db_entry->oid;
				namestrcpy(&grp->db_name, NameStr(db_entry->name));

				start_group(grp);
			}
		}

		/* Allow sinval catchup interrupts while sleeping */
		EnableCatchupInterrupt();

		/*
		 * Wait until naptime expires or we get some type of signal (all the
		 * signal handlers will wake us by calling SetLatch).
		 */
		rc = WaitLatch(&MyProc->procLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH, 0);

		ResetLatch(&MyProc->procLatch);

		DisableCatchupInterrupt();

		/*
		 * Emergency bailout if postmaster has died.  This is to avoid the
		 * necessity for manual cleanup of all postmaster children.
		 */
		if (rc & WL_POSTMASTER_DEATH)
			proc_exit(1);

		/* the normal shutdown case */
		if (got_SIGTERM)
			break;

		/* update config? */
		if (got_SIGHUP)
		{
			got_SIGHUP = false;
			ProcessConfigFile(PGC_SIGHUP);

			/* update tuning parameters, so that they can be read downstream by background processes */
			update_tuning_params();
		}

		/* terminate a proc group? */
		if (got_SIGUSR2)
		{
			HASH_SEQ_STATUS status;
			ContQueryProcGroup *grp;

			got_SIGUSR2 = false;

			hash_seq_init(&status, ContQuerySchedulerShmem->proc_table);
			while ((grp = (ContQueryProcGroup *) hash_seq_search(&status)) != NULL)
			{
				ListCell *lc;

				if (!grp->terminate)
					continue;

				foreach(lc, dbs)
				{
					DatabaseEntry *entry = lfirst(lc);
					if (entry->oid == grp->db_oid)
					{
						dbs = list_delete(dbs, entry);
						break;
					}
				}

				terminate_group(grp);
			}
		}
예제 #18
0
파일: backoff.c 프로젝트: adam8157/gpdb
/**
 * This method is called after fork of the sweeper process. It sets up signal
 * handlers and does initialization that is required by a postgres backend.
 */
NON_EXEC_STATIC void
BackoffSweeperMain(int argc, char *argv[])
{
	sigjmp_buf	local_sigjmp_buf;

	IsUnderPostmaster = true;
	isSweeperProcess = true;

	/* Stay away from PMChildSlot */
	MyPMChildSlot = -1;

	/* reset MyProcPid */
	MyProcPid = getpid();

	/* Lose the postmaster's on-exit routines */
	on_exit_reset();

	/* Identify myself via ps */
	init_ps_display("sweeper process", "", "", "");

	SetProcessingMode(InitProcessing);

	/*
	 * Set up signal handlers.  We operate on databases much like a regular
	 * backend, so we use the same signal handling.  See equivalent code in
	 * tcop/postgres.c.
	 */
	pqsignal(SIGHUP, SIG_IGN);
	pqsignal(SIGINT, SIG_IGN);
	pqsignal(SIGALRM, SIG_IGN);
	pqsignal(SIGPIPE, SIG_IGN);
	pqsignal(SIGUSR1, SIG_IGN);

	pqsignal(SIGTERM, die);
	pqsignal(SIGQUIT, quickdie);
	pqsignal(SIGUSR2, BackoffRequestShutdown);

	pqsignal(SIGFPE, FloatExceptionHandler);
	pqsignal(SIGCHLD, SIG_DFL);

	/*
	 * Copied from bgwriter
	 */
	CurrentResourceOwner = ResourceOwnerCreate(NULL, "Sweeper process");

	/* Early initialization */
	BaseInit();

	/* See InitPostgres()... */
	InitProcess();

	SetProcessingMode(NormalProcessing);

	/*
	 * If an exception is encountered, processing resumes here.
	 *
	 * See notes in postgres.c about the design of this coding.
	 */
	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
	{
		/* Prevents interrupts while cleaning up */
		HOLD_INTERRUPTS();

		/* Report the error to the server log */
		EmitErrorReport();

		/*
		 * We can now go away.  Note that because we'll call InitProcess, a
		 * callback will be registered to do ProcKill, which will clean up
		 * necessary state.
		 */
		proc_exit(0);
	}

	/* We can now handle ereport(ERROR) */
	PG_exception_stack = &local_sigjmp_buf;

	PG_SETMASK(&UnBlockSig);

	MyBackendId = InvalidBackendId;

	/* main loop */
	BackoffSweeperLoop();

	/* One iteration done, go away */
	proc_exit(0);
}
예제 #19
0
void
InitPostgres(char *name)	/* database name */
{
    bool	bootstrap;	/* true if BootstrapProcessing */
    
    /* ----------------
     *	see if we're running in BootstrapProcessing mode
     * ----------------
     */
    bootstrap = IsBootstrapProcessingMode();
    
    /* ----------------
     *	turn on the exception handler.  Note: we cannot use elog, Assert,
     *  AssertState, etc. until after exception handling is on.
     * ----------------
     */
    EnableExceptionHandling(true);
    
    /* ----------------
     *	A stupid check to make sure we don't call this more than once.
     *  But things like ReinitPostgres() get around this by just diddling
     *	the PostgresIsInitialized flag.
     * ----------------
     */
    AssertState(!PostgresIsInitialized);
    
    /* ----------------
     *	Memory system initialization.
     *  (we may call palloc after EnableMemoryContext())
     *
     *  Note EnableMemoryContext() must happen before EnablePortalManager().
     * ----------------
     */
    EnableMemoryContext(true);	/* initializes the "top context" */
    EnablePortalManager(true);	/* memory for portal/transaction stuff */
    
    /* ----------------
     *	initialize the backend local portal stack used by
     *  internal PQ function calls.  see src/lib/libpq/be-dumpdata.c
     *  This is different from the "portal manager" so this goes here.
     *  -cim 2/12/91
     * ----------------
     */    
    be_portalinit();
    
    /* ----------------
     *	 attach to shared memory and semaphores, and initialize our
     *   input/output/debugging file descriptors.
     * ----------------
     */
    InitCommunication();
    InitStdio();
    
    /*
     * initialize the local buffer manager
     */
    InitLocalBuffer();

    if (!TransactionFlushEnabled())
        on_exitpg(FlushBufferPool, (caddr_t) NULL);
    
    /* ----------------
     *	check for valid "meta gunk" (??? -cim 10/5/90) and change to
     *  database directory.
     *
     *  Note:  DatabaseName, MyDatabaseName, and DatabasePath are all
     *  initialized with DatabaseMetaGunkIsConsistent(), strncpy() and
     *  DoChdirAndInitDatabase() below!  XXX clean this crap up!
     *  -cim 10/5/90
     * ----------------
     */
    {
	char  myPath[MAXPGPATH] = ".";	/* DatabasePath points here! */
	
	/* ----------------
	 *  DatabaseMetaGunkIsConsistent fills in myPath, but what about
	 *  when bootstrap or Noversion is true?? -cim 10/5/90
	 * ----------------
	 */
	
	if (! bootstrap &&
	    ! DatabaseMetaGunkIsConsistent(name, myPath) &&
	    ! Noversion) {
	    elog(NOTICE, "InitPostgres: could not locate valid PG_VERSION\n");
	    elog(NOTICE, "files for %s and %s.", DataDir, name);
	    elog(FATAL,  "Have you run initdb/createdb and set PGDATA properly?");
	}
	
	/* ----------------
	 *  ok, we've figured out myName and myPath, now save these
	 *  and chdir to myPath.
	 * ----------------
	 */
	DoChdirAndInitDatabaseNameAndPath(name, myPath);
    }
    
    /* ********************************
     *	code after this point assumes we are in the proper directory!
     * ********************************
     */
    
    /* ----------------
     *	initialize the database id used for system caches and lock tables
     * ----------------
     */
    InitMyDatabaseId();
    
    smgrinit();
    
    /* ----------------
     *	initialize the transaction system and the relation descriptor
     *  cache.  Note we have to make certain the lock manager is off while
     *  we do this.
     * ----------------
     */
    AmiTransactionOverride(IsBootstrapProcessingMode());
    LockDisable(true);
    
    /*
     * Part of the initialization processing done here sets a read
     * lock on pg_log.  Since locking is disabled the set doesn't have
     * intended effect of locking out writers, but this is ok, since
     * we only lock it to examine AMI transaction status, and this is
     * never written after initdb is done. -mer 15 June 1992
     */
    RelationInitialize();	   /* pre-allocated reldescs created here */
    InitializeTransactionSystem(); /* pg_log,etc init/crash recovery here */
    
    LockDisable(false);
    
    /* ----------------
     *	anyone knows what this does?  something having to do with
     *  system catalog cache invalidation in the case of multiple
     *  backends, I think -cim 10/3/90
     *  Sets up MyBackendId a unique backend identifier.
     * ----------------
     */
    InitSharedInvalidationState();
    
    /* ----------------
     * Set up a per backend process in shared memory.  Must be done after
     * InitSharedInvalidationState() as it relies on MyBackendId being
     * initialized already.  XXX -mer 11 Aug 1991
     * ----------------
     */
    InitProcess(PostgresIpcKey);
    
    if (MyBackendId > MaxBackendId || MyBackendId <= 0) {
	elog(FATAL, "cinit2: bad backend id %d (%d)",
	     MyBackendTag,
	     MyBackendId);
    }
    
    /* ----------------
     *  initialize the access methods.
     * ----------------
     */
    initam();
    
    /* ----------------
     *	initialize all the system catalog caches.
     * ----------------
     */
    zerocaches();
    InitCatalogCache();
    
    /* ----------------
     *   set ourselves to the proper user id and figure out our postgres
     *   user id.  If we ever add security so that we check for valid
     *   postgres users, we might do it here.
     * ----------------
     */
    InitUserid();
    
    /* ----------------
     *	ok, all done, now let's make sure we don't do it again.
     * ----------------
     */
    PostgresIsInitialized = true;
/*    on_exitpg(DestroyLocalRelList, (caddr_t) NULL); */
    
    /* ----------------
     *  Done with "InitPostgres", now change to NormalProcessing unless
     *  we're in BootstrapProcessing mode.
     * ----------------
     */
    if (!bootstrap)
	SetProcessingMode(NormalProcessing);
/*    if (testFlag || lockingOff) */
    if (lockingOff)
	LockDisable(true);
}
예제 #20
0
//
// Driver must call this first, once, before doing any other compiler operations.
// Subsequent calls to this function are no-op.
//
int ShInitialize()
{
    static const bool kInitialized = InitProcess();
    return kInitialized ? 1 : 0;
}
예제 #21
0
파일: fts.c 프로젝트: LJoNe/gpdb
/*
 * FtsProbeMain
 */
NON_EXEC_STATIC void
ftsMain(int argc, char *argv[])
{
	sigjmp_buf	local_sigjmp_buf;
	char	   *fullpath;

	IsUnderPostmaster = true;
	am_ftsprobe = true;

	/* Stay away from PMChildSlot */
	MyPMChildSlot = -1;

	/* reset MyProcPid */
	MyProcPid = getpid();
	
	/* Lose the postmaster's on-exit routines */
	on_exit_reset();

	/* Identify myself via ps */
	init_ps_display("ftsprobe process", "", "", "");

	SetProcessingMode(InitProcessing);

	/*
	 * reread postgresql.conf if requested
	 */
	pqsignal(SIGHUP, sigHupHandler);

	/*
	 * Presently, SIGINT will lead to autovacuum shutdown, because that's how
	 * we handle ereport(ERROR).  It could be improved however.
	 */
	pqsignal(SIGINT, ReqFtsFullScan);		/* request full-scan */
	pqsignal(SIGTERM, die);
	pqsignal(SIGQUIT, quickdie); /* we don't do any ftsprobe specific cleanup, just use the standard. */
	pqsignal(SIGALRM, handle_sig_alarm);

	pqsignal(SIGPIPE, SIG_IGN);
	pqsignal(SIGUSR1, procsignal_sigusr1_handler);
	/* We don't listen for async notifies */
	pqsignal(SIGUSR2, RequestShutdown);
	pqsignal(SIGFPE, FloatExceptionHandler);
	pqsignal(SIGCHLD, SIG_DFL);

	/*
	 * Copied from bgwriter
	 */
	CurrentResourceOwner = ResourceOwnerCreate(NULL, "FTS Probe");

	/* Early initialization */
	BaseInit();

	/* See InitPostgres()... */
	InitProcess();	
	InitBufferPoolBackend();
	InitXLOGAccess();

	SetProcessingMode(NormalProcessing);

	/*
	 * If an exception is encountered, processing resumes here.
	 *
	 * See notes in postgres.c about the design of this coding.
	 */
	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
	{
		/* Prevents interrupts while cleaning up */
		HOLD_INTERRUPTS();

		/* Report the error to the server log */
		EmitErrorReport();

		/*
		 * We can now go away.	Note that because we'll call InitProcess, a
		 * callback will be registered to do ProcKill, which will clean up
		 * necessary state.
		 */
		proc_exit(0);
	}

	/* We can now handle ereport(ERROR) */
	PG_exception_stack = &local_sigjmp_buf;

	PG_SETMASK(&UnBlockSig);

	/*
	 * Add my PGPROC struct to the ProcArray.
	 *
	 * Once I have done this, I am visible to other backends!
	 */
	InitProcessPhase2();

	/*
	 * Initialize my entry in the shared-invalidation manager's array of
	 * per-backend data.
	 *
	 * Sets up MyBackendId, a unique backend identifier.
	 */
	MyBackendId = InvalidBackendId;

	SharedInvalBackendInit(false);

	if (MyBackendId > MaxBackends || MyBackendId <= 0)
		elog(FATAL, "bad backend id: %d", MyBackendId);

	/*
	 * bufmgr needs another initialization call too
	 */
	InitBufferPoolBackend();

	/* heap access requires the rel-cache */
	RelationCacheInitialize();
	InitCatalogCache();

	/*
	 * It's now possible to do real access to the system catalogs.
	 *
	 * Load relcache entries for the system catalogs.  This must create at
	 * least the minimum set of "nailed-in" cache entries.
	 */
	RelationCacheInitializePhase2();

	/*
	 * In order to access the catalog, we need a database, and a
	 * tablespace; our access to the heap is going to be slightly
	 * limited, so we'll just use some defaults.
	 */
	if (!FindMyDatabase(probeDatabase, &MyDatabaseId, &MyDatabaseTableSpace))
		ereport(FATAL,
				(errcode(ERRCODE_UNDEFINED_DATABASE),
				 errmsg("database \"%s\" does not exit", probeDatabase)));

	/* Now we can mark our PGPROC entry with the database ID */
	/* (We assume this is an atomic store so no lock is needed) */
	MyProc->databaseId = MyDatabaseId;

	fullpath = GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace);

	SetDatabasePath(fullpath);

	RelationCacheInitializePhase3();

	/* shmem: publish probe pid */
	ftsProbeInfo->fts_probePid = MyProcPid;

	/* main loop */
	FtsLoop();

	/* One iteration done, go away */
	proc_exit(0);
}