⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 support.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
字号:
/*------------------------------------------------------------------------- * * support.c *	  BeOS Support functions * * Copyright (c) 1999-2001, Cyril VELTER * *------------------------------------------------------------------------- */#include "postgres.h"/* Support Globals */port_id		beos_dl_port_in = 0;port_id		beos_dl_port_out = 0;sem_id		beos_shm_sem;/* Global var containing the postgres path */extern char my_exec_path[];/* Shared library loading doesn't work after fork in beos. The solution is to use an exactcopy of the process and use it to perform the loading, then just map the Text and Data segmentof the add-on in our address space. Both process must have the exact same memory mapping, sowe use the postgres executable. When it's lauched with the -beossupportserver parameter, thepostgres executable just run a loop to wait command on a port. Its only action is to load the addon,the beos_dl_open will then remap the good areas in the backend address space. */image_idbeos_dl_open(char *filename){	image_id	im;	/* If a port doesn't exist, lauch support server */	if ((beos_dl_port_in <= 0) || (beos_dl_port_out <= 0))	{		/* Create communication port */		beos_dl_port_in = create_port(50, "beos_support_in");		beos_dl_port_out = create_port(50, "beos_support_in");		if ((beos_dl_port_in <= 0) || (beos_dl_port_out <= 0))		{			elog(WARNING, "error loading BeOS support server: could not create communication ports");			return B_ERROR;		}		else		{			char		Cmd[4000];			/* Build arg list */			sprintf(Cmd, "%s -beossupportserver %d %d &", my_exec_path, (int) beos_dl_port_in, (int) beos_dl_port_out);			/* Lauch process */			system(Cmd);		}	}	/* Add-on loading */	/* Send command '1' (load) to the support server */	write_port(beos_dl_port_in, 1, filename, strlen(filename) + 1);	/* Read Object Id */	read_port(beos_dl_port_out, &im, NULL, 0);	/* Checking integrity */	if (im < 0)	{		elog(WARNING, "could not load this add-on");		return B_ERROR;	}	else	{		/* Map text and data segment in our address space */		char		datas[4000];		int32		area;		int32		resu;		void	   *add;		/* read text segment id and address */		read_port(beos_dl_port_out, &area, datas, 4000);		read_port(beos_dl_port_out, (void *) &add, datas, 4000);		/* map text segment in our address space */		resu = clone_area(datas, &add, B_EXACT_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);		if (resu < 0)		{			/* If we can't map, we are in reload case */			/* delete the mapping */			resu = delete_area(area_for(add));			/* Remap */			resu = clone_area(datas, &add, B_EXACT_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);			if (resu < 0)				elog(WARNING, "could not load this add-on: map text error");		}		/* read text segment id and address */		read_port(beos_dl_port_out, &area, datas, 4000);		read_port(beos_dl_port_out, (void *) &add, datas, 4000);		/* map text segment in our address space */		resu = clone_area(datas, &add, B_EXACT_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);		if (resu < 0)		{			/* If we can't map, we are in reload case */			/* delete the mapping */			resu = delete_area(area_for(add));			/* Remap */			resu = clone_area(datas, &add, B_EXACT_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);			if (resu < 0)				elog(WARNING, "could not load this add-on: map data error");		}		return im;	}}voidbeos_dl_sym(image_id im, char *symname, void **fptr){	/* Send command '3' (get symbol) to the support server */	write_port(beos_dl_port_in, 3, symname, strlen(symname) + 1);	write_port(beos_dl_port_in, im, NULL, 0);	/* Read sym address */	read_port(beos_dl_port_out, (int32 *) (fptr), NULL, 0);	if (fptr == NULL)		elog(WARNING, "loading symbol \"%s\" failed", symname);}status_tbeos_dl_close(image_id im){	/* unload add-on */	int32		resu;	write_port(beos_dl_port_in, 2, &im, 4);	read_port(beos_dl_port_out, &resu, NULL, 0);	return resu;}/* Main support server loop */voidbeos_startup(int argc, char **argv){	if (strlen(argv[0]) >= 10 && !strcmp(argv[0] + strlen(argv[0]) - 10, "postmaster"))	{		/*		 * We are in the postmaster, create the protection semaphore for		 * shared mem remapping		 */		beos_shm_sem = create_sem(1, "beos_shm_sem");	}	if (argc > 1 && strcmp(argv[1], "-beossupportserver") == 0)	{		/* We are in the support server, run it ... */		port_id		port_in;		port_id		port_out;		/* Get back port ids from arglist */		sscanf(argv[2], "%d", (int *) (&port_in));		sscanf(argv[3], "%d", (int *) (&port_out));		/* Main server loop */		for (;;)		{			int32 opcode = 0;			char		datas[4000];			/*			 * Wait for a message from the backend : 1 : load a shared object			 * 2 : unload a shared object any other : exit support server			 */			read_port(port_in, &opcode, datas, 4000);			switch (opcode)			{					image_id	addon;					image_info	info_im;					area_info	info_ar;					void	   *fpt;					/* Load Add-On */				case 1:					/* Load shared object */					addon = load_add_on(datas);					/* send back the shared object Id */					write_port(port_out, addon, NULL, 0);					/* Get Shared Object infos */					get_image_info(addon, &info_im);					/* get text segment info */					get_area_info(area_for(info_im.text), &info_ar);					/* Send back area_id of text segment */					write_port(port_out, info_ar.area, info_ar.name, strlen(info_ar.name) + 1);					/* Send back real address of text segment */					write_port(port_out, (int) info_ar.address, info_ar.name, strlen(info_ar.name) + 1);					/* get data segment info */					get_area_info(area_for(info_im.data), &info_ar);					/* Send back area_id of data segment */					write_port(port_out, info_ar.area, info_ar.name, strlen(info_ar.name) + 1);					/* Send back real address of data segment */					write_port(port_out, (int) info_ar.address, info_ar.name, strlen(info_ar.name) + 1);					break;					/* UnLoad Add-On */				case 2:					/*					 * Unload shared object and send back the result of the					 * operation					 */					write_port(port_out, unload_add_on(*((int *) (datas))), NULL, 0);					break;					/* Cleanup and exit */				case 3:					/* read image Id on the input port */					read_port(port_in, &addon, NULL, 0);					/* Loading symbol */					fpt = NULL;					if (get_image_symbol(addon, datas, B_SYMBOL_TYPE_TEXT, &fpt) == B_OK);					{						/*						 * Sometime the loader return B_OK for an inexistant						 * function with an invalid address !!! Check that the						 * return address is in the image range						 */						get_image_info(addon, &info_im);						if ((fpt < info_im.text) ||(fpt >= (info_im.text +info_im.text_size)))							fpt = NULL;					}					/* Send back fptr of data segment */					write_port(port_out, (int32) (fpt), NULL, 0);					break;				default:					/* Free system resources */					delete_port(port_in);					delete_port(port_out);					/* Exit */					exit(0);					break;			}		}		/* Never be there */		exit(1);	}}/* The behavior of fork is broken on beos regarding shared memory. In factall shared memory areas are clones in copy on write mode in the new process.We need to do a remapping of these areas. Just afer the fork we performe thefollowing actions :	* Find all areas with a name begining by SYS_V_IPC_ in our process	(areas created by the SYSV IPC emulation functions). The name is	followed by the IPC KEY in decimal format	* For each area we do :		* 1 : Get its name		* 2 : destroy it		* 3 : find another area with the exact same name		* 4 : clone it in our address space with a different name	There is a race condition in 3-4 : if there two fork in a very short	time, in step 3 we might end up with two areas with the same name, and no	possibility to find the postmaster one. So the whole process is protected	by a semaphore which is acquires just before the fork and released in case	of fork failure or just after the end of the remapping.*/voidbeos_before_backend_startup(void){	/* Just before forking, acquire the semaphore */	if (acquire_sem(beos_shm_sem) != B_OK)		exit(1);				/* Fatal error, exiting with error */}voidbeos_backend_startup_failed(void){	/* The fork failed, just release the semaphore */	release_sem(beos_shm_sem);}voidbeos_backend_startup(void){	char		nom[50];	char		nvnom[50];	area_info	inf;	int32		cook = 0;	/* Perform the remapping process */	/* Loop in all our team areas */	while (get_next_area_info(0, &cook, &inf) == B_OK)	{		strcpy(nom, inf.name);		strcpy(nvnom, inf.name);		nom[9] = 0;		nvnom[5] = 'i';		/* Is it a SYS V area ? */		if (!strcmp(nom, "SYSV_IPC_"))		{			void	   *area_address;			area_id		area_postmaster;			/* Get the area address */			area_address = inf.address;			/* Destroy the bad area */			delete_area(inf.area);			/* Find the postmaster area */			area_postmaster = find_area(inf.name);			/* Compute new area name */			sprintf(nvnom, "SYSV_IPC %d", area_postmaster);			/* Clone it at the exact same address */			clone_area(nvnom, &area_address, B_CLONE_ADDRESS, B_READ_AREA | B_WRITE_AREA, area_postmaster);		}	}	/* remapping done release semaphore to allow other backend to startup */	release_sem(beos_shm_sem);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -