Re: Beos updates - Mailing list pgsql-patches
From | Bruce Momjian |
---|---|
Subject | Re: Beos updates |
Date | |
Msg-id | 200010281826.OAA14596@candle.pha.pa.us Whole thread Raw |
List | pgsql-patches |
Applied. Thanks. [ Charset ISO-8859-1 unsupported, converting... ] > > > >This doesn't work. There is strange wrapping. I don't care how big > the > >context diff is. Send it. > > > > OK here is the complet diff against the current tree (I also > attached it to the message). > > > cyril > > > > *** ./src/backend/port/beos/sem.c.orig Sat Oct 28 18:27:40 2000 > --- ./src/backend/port/beos/sem.c Tue Oct 10 22:21:35 2000 > *************** > *** 13,172 **** > #include <stdio.h> > #include <errno.h> > #include <OS.h> > > - // Controle d'un pool de s?maphores > - // On considere que le semId utilis? correspond bien a une area de > notre adress space > - // Les informations du pool de s?maphore sont stock?s dans cette area > int semctl(int semId,int semNum,int flag,union semun semun) > { > - > - // Recherche de l'adresse de base de l'area > int32* Address; > area_info info; > ! // printf("semctl : semid %d, semnum %d, cmd %d\ > n",semId,semNum,flag); > if (get_area_info(semId,&info)!=B_OK) > { > ! // printf("area not found\n"); > errno=EINVAL; > return -1; > } > Address=(int32*)info.address; > > - // semnum peut etre ?gal ? 0 > - // semun.array contient la valeur de d?part du s?maphore > > ! // si flag = set_all il faut d?finir la valeur du s?maphore sue > semun.array > if (flag==SETALL) > { > long i; > - // printf("setall %d\n",Address[0]); > for (i=0;i<Address[0];i++) > { > int32 cnt; > get_sem_count(Address[i+1],&cnt); > ! // printf("Set de ALl %d %d = %d\n",Address[i+ > 1],semun.array[i],cnt); > cnt-=semun.array[i]; > if (cnt > 0) > ! acquire_sem_etc(Address[i+1],cnt,0,0); > if (cnt < 0) > release_sem_etc(Address[i+1],-cnt,0); > } > return 1; > } > > ! /* si flag = SET_VAL il faut d?finir la valeur du s?maphore sur > semun.val*/ > if (flag==SETVAL) > { > int32 cnt; > get_sem_count(Address[semNum+1],&cnt); > ! // printf("semctl set val id : %d val : %d = %d\ > n",semId,semun.val,cnt); > cnt-=semun.val; > if (cnt > 0) > ! acquire_sem_etc(Address[semNum+1],cnt,0,0); > if (cnt < 0) > release_sem_etc(Address[semNum+1],-cnt,0); > return 1; > } > > ! /* si flag=rm_id il faut supprimer le s?maphore*/ > if (flag==IPC_RMID) > { > long i; > ! // Suppression des s?maphores (ils appartienent au kernel > maintenant) > thread_info ti; > - // printf("remove set\n"); > get_thread_info(find_thread(NULL),&ti); > for (i=0;i<Address[0];i++) > { > set_sem_owner(Address[i+1],ti.team); > delete_sem(Address[i+1]); > } > ! // Il faudrait supprimer en boucle toutes les area portant le > m?me nom > delete_area(semId); > return 1; > } > > ! /* si flag = GETNCNT il faut renvoyer le semaphore count*/ > if (flag==GETNCNT) > { > ! // printf("getncnt : impossible sur BeOS\n"); > ! return 0; // a faire (peut etre impossible sur Beos) > } > > ! /* si flag = GETVAL il faut renvoyer la valeur du s?maphore*/ > if (flag==GETVAL) > { > int32 cnt; > get_sem_count(Address[semNum+1],&cnt); > - // printf("semctl getval id : %d cnt : %d\n",semId,cnt); > return cnt; > } > ! // printf("semctl erreur\n"); > return 0; > } > > ! // L'area dans laquelle est stock?e le pool est identifi?e par son > nom (convention ? moi : SYSV_IPC_SEM : "semId) > int semget(int semKey, int semNum, int flags) > { > char Nom[50]; > area_id parea; > void* Address; > > ! // printf("semget get k: %d n: %d fl:%d\n",semKey,semNum,flags); > ! // Construction du nom que doit avoir l'area > sprintf(Nom,"SYSV_IPC_SEM : %d",semKey); > > ! // Recherche de l'area > parea=find_area(Nom); > > ! // L'area existe > if (parea!=B_NAME_NOT_FOUND) > { > ! // printf("area found\n"); > ! // On demande une creatrion d'un pool existant : erreur > if ((flags&IPC_CREAT)&&(flags&IPC_EXCL)) > { > - // printf("creat asking exist\n"); > errno=EEXIST; > return -1; > } > > ! // Clone de l'area et renvoi de son ID > parea=clone_area(Nom,&Address,B_ANY_ADDRESS,B_READ_AREA | > B_WRITE_AREA,parea); > return parea; > } > - // L'area n'existe pas > else > { > ! // printf("set don't exist\n"); > ! // Demande de creation > if (flags&IPC_CREAT) > { > int32* Address; > - thread_info ti; > void* Ad; > long i; > > ! // printf("create set\n"); > ! // On ne peut pas creer plus de 500 semaphores dans un pool > (limite tout ? fait arbitraire de ma part) > if (semNum>500) > { > errno=ENOSPC; > return -1; > } > ! > ! // Creation de la zone de m?moire partag?e > parea=create_area(Nom,& > Ad,B_ANY_ADDRESS,4096,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA); > if ((parea==B_BAD_VALUE)|| (parea==B_NO_MEMORY)||(parea== > B_ERROR)) > { > errno=ENOMEM; > return -1; > } > Address=(int32*)Ad; > Address[0]=semNum; > for (i=1;i<=Address[0];i++) > { > ! // Creation des s?maphores 1 par 1 > Address[i]=create_sem(0,Nom); > > if ((Address[i]==B_BAD_VALUE)|| (Address[i]== > B_NO_MEMORY)||(Address[i]==B_NO_MORE_SEMS)) > --- 13,191 ---- > #include <stdio.h> > #include <errno.h> > #include <OS.h> > + #include "utils/elog.h" > + > + > + /* Control of a semaphore pool. The pool is an area in which we > stored all > + the semIds of the pool. The first 4 bytes are the number of semaphore > allocated > + in the pool followed by SemIds */ > > int semctl(int semId,int semNum,int flag,union semun semun) > { > int32* Address; > area_info info; > ! > ! /* Try to find the pool */ > if (get_area_info(semId,&info)!=B_OK) > { > ! /* pool is invalid (BeOS area id is invalid) */ > errno=EINVAL; > return -1; > } > + > + /* Get the pool address */ > Address=(int32*)info.address; > > > ! /* semNum might be 0 */ > ! /* semun.array contain the sem initial values */ > ! > ! /* Fix the count of all sem of the pool to semun.array */ > if (flag==SETALL) > { > long i; > for (i=0;i<Address[0];i++) > { > int32 cnt; > + /* Get the current count */ > get_sem_count(Address[i+1],&cnt); > ! > ! /* Compute and set the new count (relative to the old one) > */ > cnt-=semun.array[i]; > if (cnt > 0) > ! while(acquire_sem_etc(Address[i+1],cnt,0,0)== > B_INTERRUPTED); > if (cnt < 0) > release_sem_etc(Address[i+1],-cnt,0); > } > return 1; > } > > ! /* Fix the count of one semaphore to semun.val */ > if (flag==SETVAL) > { > int32 cnt; > + /* Get the current count */ > get_sem_count(Address[semNum+1],&cnt); > ! > ! /* Compute and set the new count (relative to the old one) */ > cnt-=semun.val; > if (cnt > 0) > ! while(acquire_sem_etc(Address[semNum+1],cnt,0,0)== > B_INTERRUPTED); > if (cnt < 0) > release_sem_etc(Address[semNum+1],-cnt,0); > return 1; > } > > ! /* Delete the pool */ > if (flag==IPC_RMID) > { > long i; > ! > thread_info ti; > get_thread_info(find_thread(NULL),&ti); > + > + /* Loop over all semaphore to delete them */ > for (i=0;i<Address[0];i++) > { > + /* Don't remember why I do that */ > set_sem_owner(Address[i+1],ti.team); > + > + /* Delete the semaphore */ > delete_sem(Address[i+1]); > + > + /* Reset to an invalid semId (in case other process try to > get the infos from a cloned area */ > + Address[i+1]=0; > } > ! > ! /* Set the semaphore count to 0 */ > ! Address[0]=0; > ! > ! /* Delete the area (it might be cloned by other process. Let > them live with it, > ! in all cases semIds are 0 so if another process try to use it, > it will fail */ > delete_area(semId); > + > return 1; > } > > ! /* Get the current semaphore count */ > if (flag==GETNCNT) > { > ! /* TO BE IMPLEMENTED */ > ! elog(ERROR,"beos : semctl error : GETNCNT not implemented"); > ! return 0; > } > > ! /* Get the current semaphore count of the first semaphore in the > pool */ > if (flag==GETVAL) > { > int32 cnt; > get_sem_count(Address[semNum+1],&cnt); > return cnt; > } > ! > ! elog(ERROR,"beos : semctl error : unknown flag"); > ! > return 0; > } > > ! /* Find a pool id based on IPC key */ > int semget(int semKey, int semNum, int flags) > { > char Nom[50]; > area_id parea; > void* Address; > > ! /* Name of the area to find */ > sprintf(Nom,"SYSV_IPC_SEM : %d",semKey); > > ! /* find area */ > parea=find_area(Nom); > > ! /* Test of area existance */ > if (parea!=B_NAME_NOT_FOUND) > { > ! /* Area exist and creation is requested, error */ > if ((flags&IPC_CREAT)&&(flags&IPC_EXCL)) > { > errno=EEXIST; > return -1; > } > > ! /* Get an area clone (in case it's not in our address space) */ > ! /* TODO : a check of address space might be done to avoid > duplicate areas in the same address space*/ > parea=clone_area(Nom,&Address,B_ANY_ADDRESS,B_READ_AREA | > B_WRITE_AREA,parea); > return parea; > } > else > { > ! /* Area does not exist, but creation is requested, so create > it */ > if (flags&IPC_CREAT) > { > int32* Address; > void* Ad; > long i; > > ! /* Limit to 500 semaphore in a pool */ > if (semNum>500) > { > errno=ENOSPC; > return -1; > } > ! > ! /* Create the shared memory area which will hold the pool * > / > parea=create_area(Nom,& > Ad,B_ANY_ADDRESS,4096,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA); > if ((parea==B_BAD_VALUE)|| (parea==B_NO_MEMORY)||(parea== > B_ERROR)) > { > errno=ENOMEM; > return -1; > } > + > + /* fill up informations (sem number and sem ids) */ > Address=(int32*)Ad; > Address[0]=semNum; > for (i=1;i<=Address[0];i++) > { > ! /* Create the semaphores */ > Address[i]=create_sem(0,Nom); > > if ((Address[i]==B_BAD_VALUE)|| (Address[i]== > B_NO_MEMORY)||(Address[i]==B_NO_MORE_SEMS)) > *************** > *** 176,219 **** > } > } > > - // printf("returned %d\n",parea); > return parea; > } > - // Le pool n'existe pas et pas de demande de cr?ation > else > { > ! // printf("set does not exist no creat requested\n"); > errno=ENOENT; > return -1; > } > } > } > > ! // Op?ration sur le pool de s?maphores > int semop(int semId, struct sembuf *sops, int nsops) > { > ! // Recherche de l'adresse du pool > ! int32* Address; > area_info info; > long i; > > ! // printf("semop id : %d n: %d\n",semId,sops->sem_op); > get_area_info(semId,&info); > Address=(int32*)info.address; > if ((semId==B_BAD_VALUE)||(semId==B_NO_MEMORY)||(semId==B_ERROR)) > { > errno=EINVAL; > return -1; > } > > ! // Execution de l'action > for(i=0;i<nsops;i++) > { > ! > ! // printf("semid %d, n %d\n",Address[sops[i].sem_num+ > 1],sops[i].sem_op); > if (sops[i].sem_op < 0) > { > ! acquire_sem_etc(Address[sops[i].sem_num+1],- > sops[i].sem_op,0,0); > } > if (sops[i].sem_op > 0) > { > --- 195,237 ---- > } > } > > return parea; > } > else > { > ! /* Area does not exist and no creation is requested */ > errno=ENOENT; > return -1; > } > } > } > > ! /* Acquire or release in the semaphore pool */ > int semop(int semId, struct sembuf *sops, int nsops) > { > ! int32* Address; /*Pool address*/ > area_info info; > long i; > > ! /* Get the pool address (semId IS an area id) */ > get_area_info(semId,&info); > Address=(int32*)info.address; > + > + /* Check the validity of semId (it should be an area id) */ > if ((semId==B_BAD_VALUE)||(semId==B_NO_MEMORY)||(semId==B_ERROR)) > { > errno=EINVAL; > return -1; > } > > ! /* Perform acquire or release */ > for(i=0;i<nsops;i++) > { > ! /* For each sem in the pool, check the operation to perform */ > if (sops[i].sem_op < 0) > { > ! /* Try acuiring the semaphore till we are not inteerupted > by a signal */ > ! while (acquire_sem_etc(Address[sops[i].sem_num+1],- > sops[i].sem_op,0,0)==B_INTERRUPTED); > } > if (sops[i].sem_op > 0) > { > *** ./src/backend/port/beos/shm.c.orig Sat Oct 28 18:27:40 2000 > --- ./src/backend/port/beos/shm.c Tue Oct 10 23:18:00 2000 > *************** > *** 12,37 **** > #include <stdio.h> > #include <OS.h> > > ! // Detachement d'une zone de m?moire partag?e > ! // On detruit le clone de l'area dans notre adress-space > int shmdt(char* shmaddr) > { > ! // Recherche de l'id de l'area pr?sente ? cette adresse > area_id s; > s=area_for(shmaddr); > ! // printf("detach area %d\n",s); > ! > ! // Suppression de l'area > return delete_area(s); > } > > ! // Attachement ? une zone de m?moire partag?e > ! // L'area doit bien partie de notre adress-space et on retourne > directement l'adress > int* shmat(int memId,int m1,int m2) > { > ! // printf("shmat %d %d %d\n",memId,m1,m2); > ! > ! // Lecture de notre team_id > thread_info thinfo; > team_info teinfo; > area_info ainfo; > --- 12,36 ---- > #include <stdio.h> > #include <OS.h> > > ! /* Emulating SYS shared memory with beos areas. WARNING : fork clone > ! areas in copy on write mode */ > ! > ! > ! /* Detach from a shared mem area based on its address */ > int shmdt(char* shmaddr) > { > ! /* Find area id for this address */ > area_id s; > s=area_for(shmaddr); > ! > ! /* Delete area */ > return delete_area(s); > } > > ! /* Attach to an existing area */ > int* shmat(int memId,int m1,int m2) > { > ! /* Get our team id */ > thread_info thinfo; > team_info teinfo; > area_info ainfo; > *************** > *** 39,112 **** > get_thread_info(find_thread(NULL),&thinfo); > get_team_info(thinfo.team,&teinfo); > > ! // Lecture du teamid de l'area > if (get_area_info(memId,&ainfo)!=B_OK) > printf("AREA %d Invalide\n",memId); > > if (ainfo.team==teinfo.team) > { > ! //retour de l'adresse > ! // printf("attach area %d add %d\n",memId,ainfo.address); > return (int*)ainfo.address; > } > else > { > ! // Clone de l'area > area_id narea; > narea = clone_area(ainfo.name,& > (ainfo.address),B_CLONE_ADDRESS,B_READ_AREA | B_WRITE_AREA,memId); > get_area_info(narea,&ainfo); > - // printf("attach area %d in %d add %d\ > n",memId,narea,ainfo.address); > return (int*)ainfo.address; > } > } > > ! // Utilis? uniquement pour supprimer une zone de m?moire partag?e > ! // On fait la meme chose que le detach mais avec un id direct > int shmctl(int shmid,int flag, struct shmid_ds* dummy) > { > ! // printf("shmctl %d %d \n",shmid,flag); > delete_area(shmid); > return 0; > } > > ! // Recup?ration d'une area en fonction de sa r?f?rence > ! // L'area source est identifi?e par son nom (convention ? moi : > SYSV_IPC_SHM : "memId) > int shmget(int memKey,int size,int flag) > { > - int32 n_size; > char nom[50]; > - area_id parea; > void* Address; > ! area_id a; > ! > ! n_size=((size/4096)+1)*4096; > ! > ! // printf("shmget %d %d %d %d\n",memKey,size,flag,nsize); > > ! // Determination du nom que doit avoir l'area > sprintf(nom,"SYSV_IPC_SHM : %d",memKey); > > ! > ! // Recherche de cette area > parea=find_area(nom); > > ! // L'area existe > if (parea!=B_NAME_NOT_FOUND) > { > - // printf("area found\n"); > return parea; > } > > ! // L'area n'existe pas et on n'en demande pas la cr?ation : erreur > if (flag==0) > { > - // printf("area %s not found\n",nom); > return -1; > } > > ! // L'area n'existe pas mais on demande sa cr?ation > ! a=create_area(nom,& > Address,B_ANY_ADDRESS,n_size,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA); > ! // printf("area %s : %d created addresse %d\n",nom,a,Address); > ! return a; > } > > --- 38,96 ---- > get_thread_info(find_thread(NULL),&thinfo); > get_team_info(thinfo.team,&teinfo); > > ! /* Get area teamid */ > if (get_area_info(memId,&ainfo)!=B_OK) > printf("AREA %d Invalide\n",memId); > > if (ainfo.team==teinfo.team) > { > ! /* the area is already in our address space, just return the > address */ > return (int*)ainfo.address; > } > else > { > ! /* the area is not in our address space, clone it before and > return the address */ > area_id narea; > narea = clone_area(ainfo.name,& > (ainfo.address),B_CLONE_ADDRESS,B_READ_AREA | B_WRITE_AREA,memId); > get_area_info(narea,&ainfo); > return (int*)ainfo.address; > } > } > > ! /* Control a shared mem area : Used only to delete it */ > int shmctl(int shmid,int flag, struct shmid_ds* dummy) > { > ! /* Delete the area */ > delete_area(shmid); > return 0; > } > > ! /* Get an area based on the IPC key */ > int shmget(int memKey,int size,int flag) > { > char nom[50]; > void* Address; > ! area_id parea; > > ! /* Area name */ > sprintf(nom,"SYSV_IPC_SHM : %d",memKey); > > ! /* Find area */ > parea=find_area(nom); > > ! /* area exist, just return its id */ > if (parea!=B_NAME_NOT_FOUND) > { > return parea; > } > > ! /* area does not exist and no creation is requested : error */ > if (flag==0) > { > return -1; > } > > ! /* area does not exist and its creation is requested, create it (be > sure to have a 4ko multiple size */ > ! return create_area(nom,&Address,B_ANY_ADDRESS,((size/4096)+1)* > 4096,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA); > } > > *** ./src/backend/port/beos/support.c.orig Sat Oct 28 18:27:40 2000 > --- ./src/backend/port/beos/support.c Sun Oct 15 23:30:35 2000 > *************** > *** 11,57 **** > #include "postgres.h" > > /* Support Globals */ > - char* self_binary=NULL; > port_id beos_dl_port_in=0; > port_id beos_dl_port_out=0; > sem_id beos_shm_sem; > > image_id beos_dl_open(char * filename) > { > image_id im; > > ! /* Start the support server */ > ! if (self_binary==NULL) > ! { > ! /* Can't start support server without binary name */ > ! elog(NOTICE, "Error loading BeOS support server : can't find > binary"); > ! return B_ERROR; > ! } > ! else > { > ! /* 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(NOTICE, "Error loading BeOS support server : can't > create communication ports"); > ! return B_ERROR; > ! } > ! else > ! { > ! char Cmd[4000]; > ! > ! /* Build arg list */ > ! sprintf(Cmd,"%s -beossupportserver %d %d & > ",self_binary,(int)beos_dl_port_in,(int)beos_dl_port_out); > ! > ! /* Lauch process */ > ! system(Cmd); > ! } > } > } > > --- 11,58 ---- > #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 pg_pathname[]; > + > + > + /* Shared library loading doesn't work after fork in beos. The > solution is to use an exact > + copy of the process and use it to perform the loading, then just map > the Text and Data segment > + of the add-on in our address space. Both process must have the exact > same memory mapping, so > + we use the postgres executable. When it's lauched with the - > beossupportserver parameter, the > + postgres 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_id beos_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(NOTICE, "Error loading BeOS support server : can't > create communication ports"); > ! return B_ERROR; > ! } > ! else > ! { > ! char Cmd[4000]; > ! > ! /* Build arg list */ > ! sprintf(Cmd,"%s -beossupportserver %d %d & > ",pg_pathname,(int)beos_dl_port_in,(int)beos_dl_port_out); > > ! /* Lauch process */ > ! system(Cmd); > } > } > > *************** > *** 132,143 **** > { > if (strlen(argv[0]) >= 10 && !strcmp(argv[0] + strlen(argv[0]) - > 10, "postmaster")) > { > ! /* Shared memory cloning protection semaphore */ > beos_shm_sem=create_sem(1,"beos_shm_sem"); > } > > if (argc > 1 && strcmp(argv[1], "-beossupportserver") == 0) > { > port_id port_in; > port_id port_out; > > --- 133,146 ---- > { > 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; > > *************** > *** 211,258 **** > } > > > ! void beos_backend_startup(char * binary) > { > - team_id ct; > - thread_info inft; > char nom[50]; > char nvnom[50]; > area_info inf; > int32 cook=0; > > ! /* remember full path binary name to load dl*/ > ! self_binary=strdup(binary); > > ! /* find the current team */ > ! get_thread_info(find_thread(NULL),&inft); > ! ct=inft.team; > ! > ! /* find all area with a name begining by pgsql and destroy / clone > then */ > ! > ! /* This operation must be done by only one backend at a time */ > ! if(acquire_sem(beos_shm_sem)==B_OK) > { > ! while (get_next_area_info(0, &cook, &inf) == B_OK) > { > ! strcpy(nom,inf.name); > ! strcpy(nvnom,inf.name); > ! nom[9]=0; > ! nvnom[5]='i'; > ! if (!strcmp(nom,"SYSV_IPC_")) > ! { > ! void* add; > ! area_id ar; > ! add=inf.address; > ! delete_area(inf.area); > ! ar=find_area(inf.name); > ! clone_area(nvnom,&add,B_CLONE_ADDRESS,B_READ_AREA| > B_WRITE_AREA,ar); > ! } > ! } > ! release_sem(beos_shm_sem); > ! } > ! else > ! { > ! /* Fatal error, exiting with error */ > ! exit(1); > ! } > } > --- 214,290 ---- > } > > > ! > ! /* The behavior of fork is borken on beos regarding shared memory. In > fact > ! all 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 the > ! following 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.*/ > ! > ! void beos_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 */ > ! } > ! > ! void beos_backend_startup_failed(void) > ! { > ! /* The foek failed, just release the semaphore */ > ! release_sem(beos_shm_sem); > ! } > ! > ! > ! void beos_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); > ! /* 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); > } > *** ./src/backend/postmaster/postmaster.c.orig Sat Oct 28 01:42:23 > 2000 > --- ./src/backend/postmaster/postmaster.c Sat Oct 28 01:43:53 2000 > *************** > *** 1719,1726 **** > --- 1719,1734 ---- > fflush(stdout); > fflush(stderr); > > + #ifdef __BEOS__ > + /* Specific beos actions before backend startup */ > + beos_before_backend_startup(); > + #endif > if ((pid = fork()) == 0) > { /* child */ > + #ifdef __BEOS__ > + /* Specific beos backend stratup actions */ > + beos_backend_startup(); > + #endif > if (DoBackend(port)) > { > fprintf(stderr, "%s child[%d]: BackendStartup: backend > startup failed\n", > *************** > *** 1734,1739 **** > --- 1742,1751 ---- > /* in parent */ > if (pid < 0) > { > + #ifdef __BEOS__ > + /* Specific beos backend stratup actions */ > + beos_backend_startup_failed(); > + #endif > fprintf(stderr, "%s: BackendStartup: fork failed: %s\n", > progname, strerror(errno)); > return STATUS_ERROR; > *** ./src/backend/tcop/postgres.c.orig Sat Oct 28 18:31:06 2000 > --- ./src/backend/tcop/postgres.c Sat Oct 28 18:31:30 2000 > *************** > *** 1480,1490 **** > > if (IsUnderPostmaster) > { > - #ifdef __BEOS__ > - /* Specific beos backend stratup actions */ > - beos_backend_startup(argv[0]); > - #endif > - > /* noninteractive case: nothing should be left after switches * > / > if (errs || argc != optind || DBName == NULL) > { > --- 1480,1485 ---- > *** ./src/include/port/beos.h.orig Sat Oct 28 18:28:38 2000 > --- ./src/include/port/beos.h Sat Oct 28 02:02:17 2000 > *************** > *** 1,4 **** > --- 1,6 ---- > #include <kernel/OS.h> > + #include "kernel/image.h" > + > #define USE_POSIX_TIME > #define HAS_TEST_AND_SET > > *************** > *** 6,73 **** > > #define AF_UNIX 1 /* no domain sockets on BeOS */ > > ! #ifdef __cplusplus > ! extern "C" { > ! #endif > ! #include "kernel/image.h" > ! > ! #undef HAVE_UNION_SEMUN > ! #define HAVE_UNION_SEMUN 1 > ! #undef HAVE_SYS_SEM_H > ! #undef HAVE_SYS_SHM_H > ! > ! union semun > ! { > ! int val; > ! struct semid_ds *buf; > ! unsigned short *array; > ! }; > ! /* SYS V emulation */ > ! > ! #define IPC_RMID 256 > ! #define IPC_CREAT 512 > ! #define IPC_EXCL 1024 > ! #define IPC_PRIVATE 234564 > ! > ! #define EACCESS 2048 > ! #define EIDRM 4096 > ! > ! #define SETALL 8192 > ! #define GETNCNT 16384 > ! #define GETVAL 65536 > ! #define SETVAL 131072 > ! > ! struct sembuf > ! { > ! int sem_flg; > ! int sem_op; > ! int sem_num; > ! }; > ! > ! int semctl(int semId,int semNum,int flag,union semun); > ! int semget(int semKey, int semNum, int flags); > ! int semop(int semId, struct sembuf *sops, int flag); > ! > ! struct shmid_ds > ! { > ! int dummy; > ! }; > > ! int shmdt(char* shmaddr); > ! int* shmat(int memId,int m1,int m2); > ! int shmctl(int shmid,int flag, struct shmid_ds* dummy); > ! int shmget(int memKey,int size,int flag); > ! > ! > ! /* Support functions */ > ! /* Specific beos action made on postgres/postmaster startup */ > ! void beos_startup(int argc,char** argv); > ! /* Load a shared library */ > ! image_id beos_dl_open(char * filename); > ! /* UnLoad a shared library */ > ! status_t beos_dl_close(image_id im); > ! /* Specific beos action made on backend startup */ > ! void beos_backend_startup(char* binary); > ! #ifdef __cplusplus > ! } > ! #endif > \ No newline at end of file > --- 8,71 ---- > > #define AF_UNIX 1 /* no domain sockets on BeOS */ > > ! /* SYS V emulation */ > ! > ! #undef HAVE_UNION_SEMUN > ! #define HAVE_UNION_SEMUN 1 > ! > ! #define IPC_RMID 256 > ! #define IPC_CREAT 512 > ! #define IPC_EXCL 1024 > ! #define IPC_PRIVATE 234564 > ! > ! #define EACCESS 2048 > ! #define EIDRM 4096 > ! > ! #define SETALL 8192 > ! #define GETNCNT 16384 > ! #define GETVAL 65536 > ! #define SETVAL 131072 > ! > ! union semun > ! { > ! int val; > ! struct semid_ds *buf; > ! unsigned short *array; > ! }; > ! > ! struct sembuf > ! { > ! int sem_flg; > ! int sem_op; > ! int sem_num; > ! }; > ! > ! struct shmid_ds > ! { > ! int dummy; > ! }; > > ! int semctl(int semId,int semNum,int flag,union semun); > ! int semget(int semKey, int semNum, int flags); > ! int semop(int semId, struct sembuf *sops, int flag); > ! > ! int shmdt(char* shmaddr); > ! int* shmat(int memId,int m1,int m2); > ! int shmctl(int shmid,int flag, struct shmid_ds* dummy); > ! int shmget(int memKey,int size,int flag); > ! > ! > ! /* Support functions */ > ! > ! /* Specific beos action made on postgres/postmaster startup */ > ! void beos_startup(int argc,char** argv); > ! /* Load a shared library */ > ! image_id beos_dl_open(char * filename); > ! /* UnLoad a shared library */ > ! status_t beos_dl_close(image_id im); > ! /* Specific beos action made on backend startup */ > ! void beos_before_backend_startup(void); > ! /* Specific beos action made on backend startup */ > ! void beos_backend_startup(void); > ! /* Specific beos action made on backend startup failure*/ > ! void beos_backend_startup_failed(void); > > > *** ./src/backend/port/beos/sem.c.orig Sat Oct 28 18:27:40 2000 > --- ./src/backend/port/beos/sem.c Tue Oct 10 22:21:35 2000 > *************** > *** 13,172 **** > #include <stdio.h> > #include <errno.h> > #include <OS.h> > > - // Controle d'un pool de sémaphores > - // On considere que le semId utilisé correspond bien a une area de notre adress space > - // Les informations du pool de sémaphore sont stockés dans cette area > int semctl(int semId,int semNum,int flag,union semun semun) > { > - > - // Recherche de l'adresse de base de l'area > int32* Address; > area_info info; > ! // printf("semctl : semid %d, semnum %d, cmd %d\n",semId,semNum,flag); > if (get_area_info(semId,&info)!=B_OK) > { > ! // printf("area not found\n"); > errno=EINVAL; > return -1; > } > Address=(int32*)info.address; > > - // semnum peut etre égal à 0 > - // semun.array contient la valeur de départ du sémaphore > > ! // si flag = set_all il faut définir la valeur du sémaphore sue semun.array > if (flag==SETALL) > { > long i; > - // printf("setall %d\n",Address[0]); > for (i=0;i<Address[0];i++) > { > int32 cnt; > get_sem_count(Address[i+1],&cnt); > ! // printf("Set de ALl %d %d = %d\n",Address[i+1],semun.array[i],cnt); > cnt-=semun.array[i]; > if (cnt > 0) > ! acquire_sem_etc(Address[i+1],cnt,0,0); > if (cnt < 0) > release_sem_etc(Address[i+1],-cnt,0); > } > return 1; > } > > ! /* si flag = SET_VAL il faut définir la valeur du sémaphore sur semun.val*/ > if (flag==SETVAL) > { > int32 cnt; > get_sem_count(Address[semNum+1],&cnt); > ! // printf("semctl set val id : %d val : %d = %d\n",semId,semun.val,cnt); > cnt-=semun.val; > if (cnt > 0) > ! acquire_sem_etc(Address[semNum+1],cnt,0,0); > if (cnt < 0) > release_sem_etc(Address[semNum+1],-cnt,0); > return 1; > } > > ! /* si flag=rm_id il faut supprimer le sémaphore*/ > if (flag==IPC_RMID) > { > long i; > ! // Suppression des sémaphores (ils appartienent au kernel maintenant) > thread_info ti; > - // printf("remove set\n"); > get_thread_info(find_thread(NULL),&ti); > for (i=0;i<Address[0];i++) > { > set_sem_owner(Address[i+1],ti.team); > delete_sem(Address[i+1]); > } > ! // Il faudrait supprimer en boucle toutes les area portant le même nom > delete_area(semId); > return 1; > } > > ! /* si flag = GETNCNT il faut renvoyer le semaphore count*/ > if (flag==GETNCNT) > { > ! // printf("getncnt : impossible sur BeOS\n"); > ! return 0; // a faire (peut etre impossible sur Beos) > } > > ! /* si flag = GETVAL il faut renvoyer la valeur du sémaphore*/ > if (flag==GETVAL) > { > int32 cnt; > get_sem_count(Address[semNum+1],&cnt); > - // printf("semctl getval id : %d cnt : %d\n",semId,cnt); > return cnt; > } > ! // printf("semctl erreur\n"); > return 0; > } > > ! // L'area dans laquelle est stockée le pool est identifiée par son nom (convention à moi : SYSV_IPC_SEM : "semId) > int semget(int semKey, int semNum, int flags) > { > char Nom[50]; > area_id parea; > void* Address; > > ! // printf("semget get k: %d n: %d fl:%d\n",semKey,semNum,flags); > ! // Construction du nom que doit avoir l'area > sprintf(Nom,"SYSV_IPC_SEM : %d",semKey); > > ! // Recherche de l'area > parea=find_area(Nom); > > ! // L'area existe > if (parea!=B_NAME_NOT_FOUND) > { > ! // printf("area found\n"); > ! // On demande une creatrion d'un pool existant : erreur > if ((flags&IPC_CREAT)&&(flags&IPC_EXCL)) > { > - // printf("creat asking exist\n"); > errno=EEXIST; > return -1; > } > > ! // Clone de l'area et renvoi de son ID > parea=clone_area(Nom,&Address,B_ANY_ADDRESS,B_READ_AREA | B_WRITE_AREA,parea); > return parea; > } > - // L'area n'existe pas > else > { > ! // printf("set don't exist\n"); > ! // Demande de creation > if (flags&IPC_CREAT) > { > int32* Address; > - thread_info ti; > void* Ad; > long i; > > ! // printf("create set\n"); > ! // On ne peut pas creer plus de 500 semaphores dans un pool (limite tout à fait arbitraire de ma part) > if (semNum>500) > { > errno=ENOSPC; > return -1; > } > ! > ! // Creation de la zone de mémoire partagée > parea=create_area(Nom,&Ad,B_ANY_ADDRESS,4096,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA); > if ((parea==B_BAD_VALUE)|| (parea==B_NO_MEMORY)||(parea==B_ERROR)) > { > errno=ENOMEM; > return -1; > } > Address=(int32*)Ad; > Address[0]=semNum; > for (i=1;i<=Address[0];i++) > { > ! // Creation des sémaphores 1 par 1 > Address[i]=create_sem(0,Nom); > > if ((Address[i]==B_BAD_VALUE)|| (Address[i]==B_NO_MEMORY)||(Address[i]==B_NO_MORE_SEMS)) > --- 13,191 ---- > #include <stdio.h> > #include <errno.h> > #include <OS.h> > + #include "utils/elog.h" > + > + > + /* Control of a semaphore pool. The pool is an area in which we stored all > + the semIds of the pool. The first 4 bytes are the number of semaphore allocated > + in the pool followed by SemIds */ > > int semctl(int semId,int semNum,int flag,union semun semun) > { > int32* Address; > area_info info; > ! > ! /* Try to find the pool */ > if (get_area_info(semId,&info)!=B_OK) > { > ! /* pool is invalid (BeOS area id is invalid) */ > errno=EINVAL; > return -1; > } > + > + /* Get the pool address */ > Address=(int32*)info.address; > > > ! /* semNum might be 0 */ > ! /* semun.array contain the sem initial values */ > ! > ! /* Fix the count of all sem of the pool to semun.array */ > if (flag==SETALL) > { > long i; > for (i=0;i<Address[0];i++) > { > int32 cnt; > + /* Get the current count */ > get_sem_count(Address[i+1],&cnt); > ! > ! /* Compute and set the new count (relative to the old one) */ > cnt-=semun.array[i]; > if (cnt > 0) > ! while(acquire_sem_etc(Address[i+1],cnt,0,0)==B_INTERRUPTED); > if (cnt < 0) > release_sem_etc(Address[i+1],-cnt,0); > } > return 1; > } > > ! /* Fix the count of one semaphore to semun.val */ > if (flag==SETVAL) > { > int32 cnt; > + /* Get the current count */ > get_sem_count(Address[semNum+1],&cnt); > ! > ! /* Compute and set the new count (relative to the old one) */ > cnt-=semun.val; > if (cnt > 0) > ! while(acquire_sem_etc(Address[semNum+1],cnt,0,0)==B_INTERRUPTED); > if (cnt < 0) > release_sem_etc(Address[semNum+1],-cnt,0); > return 1; > } > > ! /* Delete the pool */ > if (flag==IPC_RMID) > { > long i; > ! > thread_info ti; > get_thread_info(find_thread(NULL),&ti); > + > + /* Loop over all semaphore to delete them */ > for (i=0;i<Address[0];i++) > { > + /* Don't remember why I do that */ > set_sem_owner(Address[i+1],ti.team); > + > + /* Delete the semaphore */ > delete_sem(Address[i+1]); > + > + /* Reset to an invalid semId (in case other process try to get the infos from a cloned area */ > + Address[i+1]=0; > } > ! > ! /* Set the semaphore count to 0 */ > ! Address[0]=0; > ! > ! /* Delete the area (it might be cloned by other process. Let them live with it, > ! in all cases semIds are 0 so if another process try to use it, it will fail */ > delete_area(semId); > + > return 1; > } > > ! /* Get the current semaphore count */ > if (flag==GETNCNT) > { > ! /* TO BE IMPLEMENTED */ > ! elog(ERROR,"beos : semctl error : GETNCNT not implemented"); > ! return 0; > } > > ! /* Get the current semaphore count of the first semaphore in the pool */ > if (flag==GETVAL) > { > int32 cnt; > get_sem_count(Address[semNum+1],&cnt); > return cnt; > } > ! > ! elog(ERROR,"beos : semctl error : unknown flag"); > ! > return 0; > } > > ! /* Find a pool id based on IPC key */ > int semget(int semKey, int semNum, int flags) > { > char Nom[50]; > area_id parea; > void* Address; > > ! /* Name of the area to find */ > sprintf(Nom,"SYSV_IPC_SEM : %d",semKey); > > ! /* find area */ > parea=find_area(Nom); > > ! /* Test of area existance */ > if (parea!=B_NAME_NOT_FOUND) > { > ! /* Area exist and creation is requested, error */ > if ((flags&IPC_CREAT)&&(flags&IPC_EXCL)) > { > errno=EEXIST; > return -1; > } > > ! /* Get an area clone (in case it's not in our address space) */ > ! /* TODO : a check of address space might be done to avoid duplicate areas in the same address space*/ > parea=clone_area(Nom,&Address,B_ANY_ADDRESS,B_READ_AREA | B_WRITE_AREA,parea); > return parea; > } > else > { > ! /* Area does not exist, but creation is requested, so create it */ > if (flags&IPC_CREAT) > { > int32* Address; > void* Ad; > long i; > > ! /* Limit to 500 semaphore in a pool */ > if (semNum>500) > { > errno=ENOSPC; > return -1; > } > ! > ! /* Create the shared memory area which will hold the pool */ > parea=create_area(Nom,&Ad,B_ANY_ADDRESS,4096,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA); > if ((parea==B_BAD_VALUE)|| (parea==B_NO_MEMORY)||(parea==B_ERROR)) > { > errno=ENOMEM; > return -1; > } > + > + /* fill up informations (sem number and sem ids) */ > Address=(int32*)Ad; > Address[0]=semNum; > for (i=1;i<=Address[0];i++) > { > ! /* Create the semaphores */ > Address[i]=create_sem(0,Nom); > > if ((Address[i]==B_BAD_VALUE)|| (Address[i]==B_NO_MEMORY)||(Address[i]==B_NO_MORE_SEMS)) > *************** > *** 176,219 **** > } > } > > - // printf("returned %d\n",parea); > return parea; > } > - // Le pool n'existe pas et pas de demande de création > else > { > ! // printf("set does not exist no creat requested\n"); > errno=ENOENT; > return -1; > } > } > } > > ! // Opération sur le pool de sémaphores > int semop(int semId, struct sembuf *sops, int nsops) > { > ! // Recherche de l'adresse du pool > ! int32* Address; > area_info info; > long i; > > ! // printf("semop id : %d n: %d\n",semId,sops->sem_op); > get_area_info(semId,&info); > Address=(int32*)info.address; > if ((semId==B_BAD_VALUE)||(semId==B_NO_MEMORY)||(semId==B_ERROR)) > { > errno=EINVAL; > return -1; > } > > ! // Execution de l'action > for(i=0;i<nsops;i++) > { > ! > ! // printf("semid %d, n %d\n",Address[sops[i].sem_num+1],sops[i].sem_op); > if (sops[i].sem_op < 0) > { > ! acquire_sem_etc(Address[sops[i].sem_num+1],-sops[i].sem_op,0,0); > } > if (sops[i].sem_op > 0) > { > --- 195,237 ---- > } > } > > return parea; > } > else > { > ! /* Area does not exist and no creation is requested */ > errno=ENOENT; > return -1; > } > } > } > > ! /* Acquire or release in the semaphore pool */ > int semop(int semId, struct sembuf *sops, int nsops) > { > ! int32* Address; /*Pool address*/ > area_info info; > long i; > > ! /* Get the pool address (semId IS an area id) */ > get_area_info(semId,&info); > Address=(int32*)info.address; > + > + /* Check the validity of semId (it should be an area id) */ > if ((semId==B_BAD_VALUE)||(semId==B_NO_MEMORY)||(semId==B_ERROR)) > { > errno=EINVAL; > return -1; > } > > ! /* Perform acquire or release */ > for(i=0;i<nsops;i++) > { > ! /* For each sem in the pool, check the operation to perform */ > if (sops[i].sem_op < 0) > { > ! /* Try acuiring the semaphore till we are not inteerupted by a signal */ > ! while (acquire_sem_etc(Address[sops[i].sem_num+1],-sops[i].sem_op,0,0)==B_INTERRUPTED); > } > if (sops[i].sem_op > 0) > { > *** ./src/backend/port/beos/shm.c.orig Sat Oct 28 18:27:40 2000 > --- ./src/backend/port/beos/shm.c Tue Oct 10 23:18:00 2000 > *************** > *** 12,37 **** > #include <stdio.h> > #include <OS.h> > > ! // Detachement d'une zone de mémoire partagée > ! // On detruit le clone de l'area dans notre adress-space > int shmdt(char* shmaddr) > { > ! // Recherche de l'id de l'area présente à cette adresse > area_id s; > s=area_for(shmaddr); > ! // printf("detach area %d\n",s); > ! > ! // Suppression de l'area > return delete_area(s); > } > > ! // Attachement à une zone de mémoire partagée > ! // L'area doit bien partie de notre adress-space et on retourne directement l'adress > int* shmat(int memId,int m1,int m2) > { > ! // printf("shmat %d %d %d\n",memId,m1,m2); > ! > ! // Lecture de notre team_id > thread_info thinfo; > team_info teinfo; > area_info ainfo; > --- 12,36 ---- > #include <stdio.h> > #include <OS.h> > > ! /* Emulating SYS shared memory with beos areas. WARNING : fork clone > ! areas in copy on write mode */ > ! > ! > ! /* Detach from a shared mem area based on its address */ > int shmdt(char* shmaddr) > { > ! /* Find area id for this address */ > area_id s; > s=area_for(shmaddr); > ! > ! /* Delete area */ > return delete_area(s); > } > > ! /* Attach to an existing area */ > int* shmat(int memId,int m1,int m2) > { > ! /* Get our team id */ > thread_info thinfo; > team_info teinfo; > area_info ainfo; > *************** > *** 39,112 **** > get_thread_info(find_thread(NULL),&thinfo); > get_team_info(thinfo.team,&teinfo); > > ! // Lecture du teamid de l'area > if (get_area_info(memId,&ainfo)!=B_OK) > printf("AREA %d Invalide\n",memId); > > if (ainfo.team==teinfo.team) > { > ! //retour de l'adresse > ! // printf("attach area %d add %d\n",memId,ainfo.address); > return (int*)ainfo.address; > } > else > { > ! // Clone de l'area > area_id narea; > narea = clone_area(ainfo.name,&(ainfo.address),B_CLONE_ADDRESS,B_READ_AREA | B_WRITE_AREA,memId); > get_area_info(narea,&ainfo); > - // printf("attach area %d in %d add %d\n",memId,narea,ainfo.address); > return (int*)ainfo.address; > } > } > > ! // Utilisé uniquement pour supprimer une zone de mémoire partagée > ! // On fait la meme chose que le detach mais avec un id direct > int shmctl(int shmid,int flag, struct shmid_ds* dummy) > { > ! // printf("shmctl %d %d \n",shmid,flag); > delete_area(shmid); > return 0; > } > > ! // Recupération d'une area en fonction de sa référence > ! // L'area source est identifiée par son nom (convention à moi : SYSV_IPC_SHM : "memId) > int shmget(int memKey,int size,int flag) > { > - int32 n_size; > char nom[50]; > - area_id parea; > void* Address; > ! area_id a; > ! > ! n_size=((size/4096)+1)*4096; > ! > ! // printf("shmget %d %d %d %d\n",memKey,size,flag,nsize); > > ! // Determination du nom que doit avoir l'area > sprintf(nom,"SYSV_IPC_SHM : %d",memKey); > > ! > ! // Recherche de cette area > parea=find_area(nom); > > ! // L'area existe > if (parea!=B_NAME_NOT_FOUND) > { > - // printf("area found\n"); > return parea; > } > > ! // L'area n'existe pas et on n'en demande pas la création : erreur > if (flag==0) > { > - // printf("area %s not found\n",nom); > return -1; > } > > ! // L'area n'existe pas mais on demande sa création > ! a=create_area(nom,&Address,B_ANY_ADDRESS,n_size,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA); > ! // printf("area %s : %d created addresse %d\n",nom,a,Address); > ! return a; > } > > --- 38,96 ---- > get_thread_info(find_thread(NULL),&thinfo); > get_team_info(thinfo.team,&teinfo); > > ! /* Get area teamid */ > if (get_area_info(memId,&ainfo)!=B_OK) > printf("AREA %d Invalide\n",memId); > > if (ainfo.team==teinfo.team) > { > ! /* the area is already in our address space, just return the address */ > return (int*)ainfo.address; > } > else > { > ! /* the area is not in our address space, clone it before and return the address */ > area_id narea; > narea = clone_area(ainfo.name,&(ainfo.address),B_CLONE_ADDRESS,B_READ_AREA | B_WRITE_AREA,memId); > get_area_info(narea,&ainfo); > return (int*)ainfo.address; > } > } > > ! /* Control a shared mem area : Used only to delete it */ > int shmctl(int shmid,int flag, struct shmid_ds* dummy) > { > ! /* Delete the area */ > delete_area(shmid); > return 0; > } > > ! /* Get an area based on the IPC key */ > int shmget(int memKey,int size,int flag) > { > char nom[50]; > void* Address; > ! area_id parea; > > ! /* Area name */ > sprintf(nom,"SYSV_IPC_SHM : %d",memKey); > > ! /* Find area */ > parea=find_area(nom); > > ! /* area exist, just return its id */ > if (parea!=B_NAME_NOT_FOUND) > { > return parea; > } > > ! /* area does not exist and no creation is requested : error */ > if (flag==0) > { > return -1; > } > > ! /* area does not exist and its creation is requested, create it (be sure to have a 4ko multiple size */ > ! return create_area(nom,&Address,B_ANY_ADDRESS,((size/4096)+1)*4096,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA); > } > > *** ./src/backend/port/beos/support.c.orig Sat Oct 28 18:27:40 2000 > --- ./src/backend/port/beos/support.c Sun Oct 15 23:30:35 2000 > *************** > *** 11,57 **** > #include "postgres.h" > > /* Support Globals */ > - char* self_binary=NULL; > port_id beos_dl_port_in=0; > port_id beos_dl_port_out=0; > sem_id beos_shm_sem; > > image_id beos_dl_open(char * filename) > { > image_id im; > > ! /* Start the support server */ > ! if (self_binary==NULL) > ! { > ! /* Can't start support server without binary name */ > ! elog(NOTICE, "Error loading BeOS support server : can't find binary"); > ! return B_ERROR; > ! } > ! else > { > ! /* 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(NOTICE, "Error loading BeOS support server : can't create communication ports"); > ! return B_ERROR; > ! } > ! else > ! { > ! char Cmd[4000]; > ! > ! /* Build arg list */ > ! sprintf(Cmd,"%s -beossupportserver %d %d &",self_binary,(int)beos_dl_port_in,(int)beos_dl_port_out); > ! > ! /* Lauch process */ > ! system(Cmd); > ! } > } > } > > --- 11,58 ---- > #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 pg_pathname[]; > + > + > + /* Shared library loading doesn't work after fork in beos. The solution is to use an exact > + copy of the process and use it to perform the loading, then just map the Text and Data segment > + of the add-on in our address space. Both process must have the exact same memory mapping, so > + we use the postgres executable. When it's lauched with the -beossupportserver parameter, the > + postgres 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_id beos_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(NOTICE, "Error loading BeOS support server : can't create communication ports"); > ! return B_ERROR; > ! } > ! else > ! { > ! char Cmd[4000]; > ! > ! /* Build arg list */ > ! sprintf(Cmd,"%s -beossupportserver %d %d &",pg_pathname,(int)beos_dl_port_in,(int)beos_dl_port_out); > > ! /* Lauch process */ > ! system(Cmd); > } > } > > *************** > *** 132,143 **** > { > if (strlen(argv[0]) >= 10 && !strcmp(argv[0] + strlen(argv[0]) - 10, "postmaster")) > { > ! /* Shared memory cloning protection semaphore */ > beos_shm_sem=create_sem(1,"beos_shm_sem"); > } > > if (argc > 1 && strcmp(argv[1], "-beossupportserver") == 0) > { > port_id port_in; > port_id port_out; > > --- 133,146 ---- > { > 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; > > *************** > *** 211,258 **** > } > > > ! void beos_backend_startup(char * binary) > { > - team_id ct; > - thread_info inft; > char nom[50]; > char nvnom[50]; > area_info inf; > int32 cook=0; > > ! /* remember full path binary name to load dl*/ > ! self_binary=strdup(binary); > > ! /* find the current team */ > ! get_thread_info(find_thread(NULL),&inft); > ! ct=inft.team; > ! > ! /* find all area with a name begining by pgsql and destroy / clone then */ > ! > ! /* This operation must be done by only one backend at a time */ > ! if(acquire_sem(beos_shm_sem)==B_OK) > { > ! while (get_next_area_info(0, &cook, &inf) == B_OK) > { > ! strcpy(nom,inf.name); > ! strcpy(nvnom,inf.name); > ! nom[9]=0; > ! nvnom[5]='i'; > ! if (!strcmp(nom,"SYSV_IPC_")) > ! { > ! void* add; > ! area_id ar; > ! add=inf.address; > ! delete_area(inf.area); > ! ar=find_area(inf.name); > ! clone_area(nvnom,&add,B_CLONE_ADDRESS,B_READ_AREA|B_WRITE_AREA,ar); > ! } > ! } > ! release_sem(beos_shm_sem); > ! } > ! else > ! { > ! /* Fatal error, exiting with error */ > ! exit(1); > ! } > } > --- 214,290 ---- > } > > > ! > ! /* The behavior of fork is borken on beos regarding shared memory. In fact > ! all 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 the > ! following 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.*/ > ! > ! void beos_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 */ > ! } > ! > ! void beos_backend_startup_failed(void) > ! { > ! /* The foek failed, just release the semaphore */ > ! release_sem(beos_shm_sem); > ! } > ! > ! > ! void beos_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); > ! /* 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); > } > *** ./src/backend/postmaster/postmaster.c.orig Sat Oct 28 01:42:23 2000 > --- ./src/backend/postmaster/postmaster.c Sat Oct 28 01:43:53 2000 > *************** > *** 1719,1726 **** > --- 1719,1734 ---- > fflush(stdout); > fflush(stderr); > > + #ifdef __BEOS__ > + /* Specific beos actions before backend startup */ > + beos_before_backend_startup(); > + #endif > if ((pid = fork()) == 0) > { /* child */ > + #ifdef __BEOS__ > + /* Specific beos backend stratup actions */ > + beos_backend_startup(); > + #endif > if (DoBackend(port)) > { > fprintf(stderr, "%s child[%d]: BackendStartup: backend startup failed\n", > *************** > *** 1734,1739 **** > --- 1742,1751 ---- > /* in parent */ > if (pid < 0) > { > + #ifdef __BEOS__ > + /* Specific beos backend stratup actions */ > + beos_backend_startup_failed(); > + #endif > fprintf(stderr, "%s: BackendStartup: fork failed: %s\n", > progname, strerror(errno)); > return STATUS_ERROR; > *** ./src/backend/tcop/postgres.c.orig Sat Oct 28 18:31:06 2000 > --- ./src/backend/tcop/postgres.c Sat Oct 28 18:31:30 2000 > *************** > *** 1480,1490 **** > > if (IsUnderPostmaster) > { > - #ifdef __BEOS__ > - /* Specific beos backend stratup actions */ > - beos_backend_startup(argv[0]); > - #endif > - > /* noninteractive case: nothing should be left after switches */ > if (errs || argc != optind || DBName == NULL) > { > --- 1480,1485 ---- > *** ./src/include/port/beos.h.orig Sat Oct 28 18:28:38 2000 > --- ./src/include/port/beos.h Sat Oct 28 02:02:17 2000 > *************** > *** 1,4 **** > --- 1,6 ---- > #include <kernel/OS.h> > + #include "kernel/image.h" > + > #define USE_POSIX_TIME > #define HAS_TEST_AND_SET > > *************** > *** 6,73 **** > > #define AF_UNIX 1 /* no domain sockets on BeOS */ > > ! #ifdef __cplusplus > ! extern "C" { > ! #endif > ! #include "kernel/image.h" > ! > ! #undef HAVE_UNION_SEMUN > ! #define HAVE_UNION_SEMUN 1 > ! #undef HAVE_SYS_SEM_H > ! #undef HAVE_SYS_SHM_H > ! > ! union semun > ! { > ! int val; > ! struct semid_ds *buf; > ! unsigned short *array; > ! }; > ! /* SYS V emulation */ > ! > ! #define IPC_RMID 256 > ! #define IPC_CREAT 512 > ! #define IPC_EXCL 1024 > ! #define IPC_PRIVATE 234564 > ! > ! #define EACCESS 2048 > ! #define EIDRM 4096 > ! > ! #define SETALL 8192 > ! #define GETNCNT 16384 > ! #define GETVAL 65536 > ! #define SETVAL 131072 > ! > ! struct sembuf > ! { > ! int sem_flg; > ! int sem_op; > ! int sem_num; > ! }; > ! > ! int semctl(int semId,int semNum,int flag,union semun); > ! int semget(int semKey, int semNum, int flags); > ! int semop(int semId, struct sembuf *sops, int flag); > ! > ! struct shmid_ds > ! { > ! int dummy; > ! }; > > ! int shmdt(char* shmaddr); > ! int* shmat(int memId,int m1,int m2); > ! int shmctl(int shmid,int flag, struct shmid_ds* dummy); > ! int shmget(int memKey,int size,int flag); > ! > ! > ! /* Support functions */ > ! /* Specific beos action made on postgres/postmaster startup */ > ! void beos_startup(int argc,char** argv); > ! /* Load a shared library */ > ! image_id beos_dl_open(char * filename); > ! /* UnLoad a shared library */ > ! status_t beos_dl_close(image_id im); > ! /* Specific beos action made on backend startup */ > ! void beos_backend_startup(char* binary); > ! #ifdef __cplusplus > ! } > ! #endif > \ No newline at end of file > --- 8,71 ---- > > #define AF_UNIX 1 /* no domain sockets on BeOS */ > > ! /* SYS V emulation */ > ! > ! #undef HAVE_UNION_SEMUN > ! #define HAVE_UNION_SEMUN 1 > ! > ! #define IPC_RMID 256 > ! #define IPC_CREAT 512 > ! #define IPC_EXCL 1024 > ! #define IPC_PRIVATE 234564 > ! > ! #define EACCESS 2048 > ! #define EIDRM 4096 > ! > ! #define SETALL 8192 > ! #define GETNCNT 16384 > ! #define GETVAL 65536 > ! #define SETVAL 131072 > ! > ! union semun > ! { > ! int val; > ! struct semid_ds *buf; > ! unsigned short *array; > ! }; > ! > ! struct sembuf > ! { > ! int sem_flg; > ! int sem_op; > ! int sem_num; > ! }; > ! > ! struct shmid_ds > ! { > ! int dummy; > ! }; > > ! int semctl(int semId,int semNum,int flag,union semun); > ! int semget(int semKey, int semNum, int flags); > ! int semop(int semId, struct sembuf *sops, int flag); > ! > ! int shmdt(char* shmaddr); > ! int* shmat(int memId,int m1,int m2); > ! int shmctl(int shmid,int flag, struct shmid_ds* dummy); > ! int shmget(int memKey,int size,int flag); > ! > ! > ! /* Support functions */ > ! > ! /* Specific beos action made on postgres/postmaster startup */ > ! void beos_startup(int argc,char** argv); > ! /* Load a shared library */ > ! image_id beos_dl_open(char * filename); > ! /* UnLoad a shared library */ > ! status_t beos_dl_close(image_id im); > ! /* Specific beos action made on backend startup */ > ! void beos_before_backend_startup(void); > ! /* Specific beos action made on backend startup */ > ! void beos_backend_startup(void); > ! /* Specific beos action made on backend startup failure*/ > ! void beos_backend_startup_failed(void); > [ application/x-be_attribute is not supported, skipping... ] -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000 + If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania 19026
pgsql-patches by date: