int main(int argc, char* argv[]) { int shmid ; char line[128]; int fd_s, fd_r ; //open fifo 12.fifp 21.fifo fd_s = open("./12.fifo", O_WRONLY); fd_r = open("./21.fifo", O_RDONLY); printf("fd_s: %d, fd_r: %d\n", fd_s, fd_r); //shm shmid = shmget((key_t)1234, sizeof(mem_t), IPC_CREAT|0666); if(shmid == -1) { perror("shmget"); exit(1); } pmem_t pm = (pmem_t)shmat(shmid, NULL, 0); if((void*)pm == (void*)-1) { perror("shmat"); exit(1); } pm ->m_lock = 1 ; pm ->m_unshow = 0 ; //select fd_set rds ; struct timeval tm ; int ret ; while(1) { FD_ZERO(&rds); FD_SET(0, &rds); FD_SET(fd_r, &rds); tm.tv_usec = 0 ; tm.tv_sec = 5; ret = select(1024, &rds, NULL, NULL, &tm); if(ret == 0) { continue ; }else if(ret > 0) { if(FD_ISSET(0, &rds)) { memset(line, 0, 128); read(0, line, 127); write(fd_s, line, strlen(line)); } if(FD_ISSET(fd_r, &rds )) { memset(line, 0, 128); read(fd_r, line, 127); Lock(pm); while( pm -> m_unshow == 1) { unLock(pm); sleep(1); Lock(pm); } strcpy(pm ->m_buf, line); pm ->m_unshow = 1 ; unLock(pm); } } } close(fd_s); close(fd_r); shmdt(pm); shmctl(shmid, IPC_RMID, NULL); return 0 ; }
SDL_Surface *PG_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { if ( this->hidden->bitmap ) { /* Free old bitmap */ if (current->pixels) { shmdt(current->pixels); current->pixels = NULL; } pgDelete(this->hidden->bitmap); } /* Allocate the new pixel format for the screen */ if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) { SDL_SetError("Couldn't allocate new pixel format for requested mode"); return(NULL); } /* Create a new picogui bitmap */ this->hidden->bitmap = pgCreateBitmap(width,height); this->hidden->shm = *pgMakeSHMBitmap(this->hidden->bitmap); current->pixels = shmat(shmget(this->hidden->shm.shm_key, this->hidden->shm.shm_length,0),NULL,0); /* Reset the canvas, and draw persistent and incremental grops. * Use mapping and offsets to center it. */ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_NUKE, 0); /* 0. Set the source position during incremental rendering */ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROP, 5, PG_GROP_SETSRC,0,0,0,0); pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROPFLAGS, 1, PG_GROPF_INCREMENTAL); /* 1. Incremental bitmap rendering */ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROP, 6, PG_GROP_BITMAP, 0,0,0,0,this->hidden->bitmap); pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROPFLAGS, 1, PG_GROPF_INCREMENTAL); /* 2. Normal bitmap rendering */ pgWriteCmd(this->hidden->wCanvas, PGCANVAS_GROP, 6, PG_GROP_BITMAP, 0,0,this->hidden->shm.width,this->hidden->shm.height,this->hidden->bitmap); /* Set up the new mode framebuffer */ current->flags = 0; current->w = this->hidden->shm.width; current->h = this->hidden->shm.height; current->pitch = this->hidden->shm.pitch; /* Set up pixel format */ current->format->BitsPerPixel = this->hidden->shm.bpp; current->format->BytesPerPixel = this->hidden->shm.bpp >> 3; if (this->hidden->shm.bpp & 7) current->format->BytesPerPixel++; current->format->palette = NULL; current->format->Rmask = this->hidden->shm.red_mask; current->format->Gmask = this->hidden->shm.green_mask; current->format->Bmask = this->hidden->shm.blue_mask; current->format->Amask = this->hidden->shm.alpha_mask; current->format->Rshift = this->hidden->shm.red_shift; current->format->Gshift = this->hidden->shm.green_shift; current->format->Bshift = this->hidden->shm.blue_shift; current->format->Ashift = this->hidden->shm.alpha_shift; current->format->Rloss = 8 - this->hidden->shm.red_length; current->format->Gloss = 8 - this->hidden->shm.green_length; current->format->Bloss = 8 - this->hidden->shm.blue_length; current->format->Aloss = 8 - this->hidden->shm.alpha_length; /* Draw the app */ pgUpdate(); /* We're done */ return(current); }
/* ////////////////////////////////////////////////////////////////////////// */ static int segment_create(opal_shmem_ds_t *ds_buf, const char *file_name, size_t size) { int rc = OPAL_SUCCESS; pid_t my_pid = getpid(); /* the real size of the shared memory segment. this includes enough space * to store our segment header. */ size_t real_size = size + sizeof(opal_shmem_seg_hdr_t); opal_shmem_seg_hdr_t *seg_hdrp = MAP_FAILED; /* init the contents of opal_shmem_ds_t */ shmem_ds_reset(ds_buf); /* for sysv shared memory we don't have to worry about the backing store * being located on a network file system... so no check is needed here. */ /* create a new shared memory segment and save the shmid. note the use of * real_size here */ if (-1 == (ds_buf->seg_id = shmget(IPC_PRIVATE, real_size, IPC_CREAT | IPC_EXCL | S_IRWXU))) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-sysv.txt", "sys call fail", 1, hn, "shmget(2)", "", strerror(err), err); rc = OPAL_ERROR; goto out; } /* attach to the sement */ else if ((void *)-1 == (seg_hdrp = shmat(ds_buf->seg_id, NULL, 0))) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-sysv.txt", "sys call fail", 1, hn, "shmat(2)", "", strerror(err), err); shmctl(ds_buf->seg_id, IPC_RMID, NULL); rc = OPAL_ERROR; goto out; } /* mark the segment for destruction - if we are here, then the run-time * component selection test detected adequate support for this type of * thing. */ else if (0 != shmctl(ds_buf->seg_id, IPC_RMID, NULL)) { int err = errno; char hn[MAXHOSTNAMELEN]; gethostname(hn, MAXHOSTNAMELEN - 1); hn[MAXHOSTNAMELEN - 1] = '\0'; opal_show_help("help-opal-shmem-sysv.txt", "sys call fail", 1, hn, "shmctl(2)", "", strerror(err), err); rc = OPAL_ERROR; goto out; } /* all is well */ else { /* -- initialize the shared memory segment -- */ opal_atomic_rmb(); /* init segment lock */ opal_atomic_init(&seg_hdrp->lock, OPAL_ATOMIC_UNLOCKED); /* i was the creator of this segment, so note that fact */ seg_hdrp->cpid = my_pid; opal_atomic_wmb(); /* -- initialize the contents of opal_shmem_ds_t -- */ ds_buf->seg_cpid = my_pid; ds_buf->seg_size = real_size; ds_buf->seg_base_addr = (unsigned char *)seg_hdrp; /* notice that we are not setting ds_buf->name here. sysv doesn't use * it, so don't worry about it - shmem_ds_reset took care of * initialization, so we aren't passing garbage around. */ /* set "valid" bit because setment creation was successful */ OPAL_SHMEM_DS_SET_VALID(ds_buf); OPAL_OUTPUT_VERBOSE( (70, opal_shmem_base_framework.framework_output, "%s: %s: create successful " "(id: %d, size: %lu, name: %s)\n", mca_shmem_sysv_component.super.base_version.mca_type_name, mca_shmem_sysv_component.super.base_version.mca_component_name, ds_buf->seg_id, (unsigned long)ds_buf->seg_size, ds_buf->seg_name) ); } out: /* an error occured, so invalidate the shmem object and release any * allocated resources. */ if (OPAL_SUCCESS != rc) { /* best effort to delete the segment. */ if ((void *)-1 != seg_hdrp) { shmdt((char*)seg_hdrp); } shmctl(ds_buf->seg_id, IPC_RMID, NULL); /* always invalidate in this error path */ shmem_ds_reset(ds_buf); } return rc; }
int main(int o_argc, const string const* o_argv) { string _path = getExecPath(*o_argv); key_t _key = ftok(_path, 'x'); asserts(_key, "ftok"); free(_path); _path = NULL; union semun _arg ; struct sembuf _buf ; int _shmid; MyData _data ; size_t _off ; /* Nowaday, memory is so cheap that I just do not care about the unused memory. * If is it too waste, then just compile with DYN_SEG_SIZE switch. **/ #ifndef DYN_SEG_SIZE const off_t SEG_SIZE = sizeof(mydata_t); #endif /* DYN_SEG_SIZE */ _buf.sem_num = 0; _buf.sem_flg = 0; /* Try to create a set of semaphores. */ int _semid = semget(_key, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR); if(_semid == -1) { const int MAX_TRIES = 6; /* If semget failed, and the set does not exist then exit */ if(errno != EEXIST) asserts(_semid, "semget"); _semid = semget(_key, 1, S_IRUSR | S_IWUSR); asserts(_semid); struct semid_ds _ds; _arg.buf = &_ds; for(size_t i = 0; i < MAX_TRIES; i++) { asserts( semctl(_semid, 0, IPC_STAT, _arg) ); if(_ds.sem_otime != 0) break; sleep(5); } if(_ds.sem_otime == 0) fatal ( "The set of semaphores already exists, but it is not initialized.\n" "This is a permanent error, and I have given up." ) ; } /* init semaphore */ else { /* Note: * Some systems, like Linux, implicitly initializes a set of semaphores by value 0, * but unfortunately some does not. For that reason, this operation is necessary to ensure * a portability. **/ _arg.val = 0; asserts( semctl(_semid, 0, SETVAL, _arg) ); /* post semaphore */ _buf.sem_op = 1; asserts( semop(_semid, &_buf, 1) ); } /* lock the semaphore */ _buf.sem_op = -1; asserts( semop(_semid, &_buf, 1) ); /* Critical section: */ /* there is no arguments so print shared memory object content */ if(o_argc == 1) { /* obtain the descriptor of shared memory object */ asserts( _shmid = shmget(_key, 0, S_IRUSR | S_IWUSR | SHM_RDONLY) ); /* map shared memory object into virtual address space */ assertv(_data = shmat(_shmid, NULL, 0), cast(void*)-1); /* read from shared memory object */ _off = 0; for(size_t i = 0; i < _data->len; i++) { print(_data->vals + _off); print(" "); _off += strlen(_data->vals + _off) + 1; } println(""); } /* write arguments in the reveres order into shared memory object */ else { #if (defined ALLOW_CLEANUP || defined DYN_SEG_SIZE) struct shmid_ds _shmds; #endif /* ALLOW_CLEANUP || DYN_SEG_SIZE */ #ifdef ALLOW_CLEANUP union semun _semun; /* if shared memory object already exist obtain its id and destroy, otherwise do nothing */ if( o_argc == 2 && !strcmp(o_argv[1], "cleanup") ) { _shmid = shmget(_key, 0, S_IRUSR | S_IWUSR); if(_shmid == -1) { if(errno != ENOENT) asserts(_shmid); } else asserts( shmctl(_shmid, IPC_RMID, &_shmds) ); /* destroy the semaphore before exit */ asserts( semctl(_semid, 0, IPC_RMID, _semun) ); exit(EXIT_SUCCESS); } #endif /* ALLOW_CLEANUP */ /* use existing shared memory object or create the new one */ #ifdef DYN_SEG_SIZE off_t _segSz = sizeof(size_t); for(size_t i = 1; i < o_argc; i++) { _segSz += strlen(o_argv[i]) + 1; } /* Try to create a new shared memory object. * If such object already exits the destoy it before. **/ _shmid = shmget(_key, _segSz, S_IRUSR | S_IWUSR | IPC_CREAT | IPC_EXCL); if(_shmid == -1) { if(errno == EEXIST) { asserts( _shmid = shmget(_key, 0, S_IRUSR | S_IWUSR) ); asserts( shmctl(_shmid, IPC_RMID, &_shmds) ); asserts( _shmid = shmget(_key, _segSz, S_IRUSR | S_IWUSR | IPC_CREAT) ); } } #else asserts( _shmid = shmget(_key, SEG_SIZE, S_IRUSR | S_IWUSR | IPC_CREAT) ); #endif /* DYN_SEG_SIZE */ /* map shared memory object into virtual address space */ assertv(_data = shmat(_shmid, NULL, 0), cast(void*)-1); /* write into the shared memory object */ _data->len = o_argc - 1; _off = 0; for(size_t i = o_argc - 1; i > 0; i--) { /* it is safe to use strcpy, because we got enought memory */ strcpy(_data->vals + _off, o_argv[i]); _off += strlen(o_argv[i]) + 1; } } /* unmap shared memory object from virtual address space */ assertz( shmdt(_data) ); _data = NULL; /* unlock the semaphore */ _buf.sem_op = 1; asserts( semop(_semid, &_buf, 1) ); exit(EXIT_SUCCESS); }
int main() { int rc; char s[1024]; char last_message_i_wrote[256]; char md5ified_message[256]; int i = 0; int done = 0; struct param_struct params; int shm_id; void *address = NULL; int sem_id; struct shmid_ds shm_info; say(MY_NAME, "Oooo 'ello, I'm Mrs. Premise!"); read_params(¶ms); // Create the shared memory shm_id = shmget(params.key, params.size, IPC_CREAT | IPC_EXCL | params.permissions); if (shm_id == -1) { shm_id = 0; sprintf(s, "Creating the shared memory failed; errno is %d", errno); say(MY_NAME, s); } else { sprintf(s, "Shared memory's id is %d", shm_id); say(MY_NAME, s); // Attach the memory. address = shmat(shm_id, NULL, 0); if ((void *)-1 == address) { address = NULL; sprintf(s, "Attaching the shared memory failed; errno is %d", errno); say(MY_NAME, s); } else { sprintf(s, "shared memory address = %p", address); say(MY_NAME, s); } } if (address) { // Create the semaphore sem_id = semget(params.key, 1, IPC_CREAT | IPC_EXCL | params.permissions); if (-1 == sem_id) { sem_id = 0; sprintf(s, "Creating the semaphore failed; errno is %d", errno); say(MY_NAME, s); } else { sprintf(s, "the semaphore id is %d", sem_id); say(MY_NAME, s); // I seed the shared memory with a random string (the current time). get_current_time(s); strcpy((char *)address, s); strcpy(last_message_i_wrote, s); sprintf(s, "Wrote %zu characters: %s", strlen(last_message_i_wrote), last_message_i_wrote); say(MY_NAME, s); i = 0; while (!done) { sprintf(s, "iteration %d", i); say(MY_NAME, s); // Release the semaphore... rc = release_semaphore(MY_NAME, sem_id, params.live_dangerously); // ...and wait for it to become available again. In real code // I might want to sleep briefly before calling .acquire() in // order to politely give other processes an opportunity to grab // the semaphore while it is free so as to avoid starvation. But // this code is meant to be a stress test that maximizes the // opportunity for shared memory corruption and politeness is // not helpful in stress tests. if (!rc) rc = acquire_semaphore(MY_NAME, sem_id, params.live_dangerously); if (rc) done = 1; else { // I keep checking the shared memory until something new has // been written. while ( (!rc) && \ (!strcmp((char *)address, last_message_i_wrote)) ) { // Nothing new; give Mrs. Conclusion another change to respond. sprintf(s, "Read %zu characters '%s'", strlen((char *)address), (char *)address); say(MY_NAME, s); rc = release_semaphore(MY_NAME, sem_id, params.live_dangerously); if (!rc) { rc = acquire_semaphore(MY_NAME, sem_id, params.live_dangerously); } } if (rc) done = 1; else { sprintf(s, "Read %zu characters '%s'", strlen((char *)address), (char *)address); say(MY_NAME, s); // What I read must be the md5 of what I wrote or something's // gone wrong. md5ify(last_message_i_wrote, md5ified_message); if (strcmp(md5ified_message, (char *)address) == 0) { // Yes, the message is OK i++; if (i == params.iterations) done = 1; // MD5 the reply and write back to Mrs. Conclusion. md5ify(md5ified_message, md5ified_message); sprintf(s, "Writing %zu characters '%s'", strlen(md5ified_message), md5ified_message); say(MY_NAME, s); strcpy((char *)address, md5ified_message); strcpy((char *)last_message_i_wrote, md5ified_message); } else { sprintf(s, "Shared memory corruption after %d iterations.", i); say(MY_NAME, s); sprintf(s, "Mismatch; new message is '%s', expected '%s'.", (char *)address, md5ified_message); say(MY_NAME, s); done = 1; } } } } // Announce for one last time that the semaphore is free again so that // Mrs. Conclusion can exit. say(MY_NAME, "Final release of the semaphore followed by a 5 second pause"); rc = release_semaphore(MY_NAME, sem_id, params.live_dangerously); sleep(5); // ...before beginning to wait until it is free again. // Technically, this is bad practice. It's possible that on a // heavily loaded machine, Mrs. Conclusion wouldn't get a chance // to acquire the semaphore. There really ought to be a loop here // that waits for some sort of goodbye message but for purposes of // simplicity I'm skipping that. say(MY_NAME, "Final wait to acquire the semaphore"); rc = acquire_semaphore(MY_NAME, sem_id, params.live_dangerously); if (!rc) { say(MY_NAME, "Destroying the shared memory."); if (-1 == shmdt(address)) { sprintf(s, "Detaching the memory failed; errno is %d", errno); say(MY_NAME, s); } address = NULL; if (-1 == shmctl(shm_id, IPC_RMID, &shm_info)) { sprintf(s, "Removing the memory failed; errno is %d", errno); say(MY_NAME, s); } } } say(MY_NAME, "Destroying the semaphore."); // Clean up the semaphore if (-1 == semctl(sem_id, 0, IPC_RMID)) { sprintf(s, "Removing the semaphore failed; errno is %d", errno); say(MY_NAME, s); } } return 0; }
/* * PGSharedMemoryCreate * * Create a shared memory segment of the given size and initialize its * standard header. Also, register an on_shmem_exit callback to release * the storage. * * Dead Postgres segments are recycled if found, but we do not fail upon * collision with non-Postgres shmem segments. The idea here is to detect and * re-use keys that may have been assigned by a crashed postmaster or backend. * * makePrivate means to always create a new segment, rather than attach to * or recycle any existing segment. * * The port number is passed for possible use as a key (for SysV, we use * it to generate the starting shmem key). In a standalone backend, * zero will be passed. */ PGShmemHeader * PGSharedMemoryCreate(Size size, bool makePrivate, int port) { IpcMemoryKey NextShmemSegID; void *memAddress; PGShmemHeader *hdr; IpcMemoryId shmid; struct stat statbuf; /* Room for a header? */ Assert(size > MAXALIGN(sizeof(PGShmemHeader))); /* Make sure PGSharedMemoryAttach doesn't fail without need */ UsedShmemSegAddr = NULL; /* Loop till we find a free IPC key */ NextShmemSegID = port * 1000; for (NextShmemSegID++;; NextShmemSegID++) { /* Try to create new segment */ memAddress = InternalIpcMemoryCreate(NextShmemSegID, size); if (memAddress) break; /* successful create and attach */ /* Check shared memory and possibly remove and recreate */ if (makePrivate) /* a standalone backend shouldn't do this */ continue; if ((memAddress = PGSharedMemoryAttach(NextShmemSegID, &shmid)) == NULL) continue; /* can't attach, not one of mine */ /* * If I am not the creator and it belongs to an extant process, * continue. */ hdr = (PGShmemHeader *) memAddress; if (hdr->creatorPID != getpid()) { if (kill(hdr->creatorPID, 0) == 0 || errno != ESRCH) { shmdt(memAddress); continue; /* segment belongs to a live process */ } } /* * The segment appears to be from a dead Postgres process, or from a * previous cycle of life in this same process. Zap it, if possible. * This probably shouldn't fail, but if it does, assume the segment * belongs to someone else after all, and continue quietly. */ shmdt(memAddress); if (shmctl(shmid, IPC_RMID, NULL) < 0) continue; /* * Now try again to create the segment. */ memAddress = InternalIpcMemoryCreate(NextShmemSegID, size); if (memAddress) break; /* successful create and attach */ /* * Can only get here if some other process managed to create the same * shmem key before we did. Let him have that one, loop around to try * next key. */ } /* * OK, we created a new segment. Mark it as created by this process. The * order of assignments here is critical so that another Postgres process * can't see the header as valid but belonging to an invalid PID! */ hdr = (PGShmemHeader *) memAddress; hdr->creatorPID = getpid(); hdr->magic = PGShmemMagic; /* Fill in the data directory ID info, too */ if (stat(DataDir, &statbuf) < 0) ereport(FATAL, (errcode_for_file_access(), errmsg("could not stat data directory \"%s\": %m", DataDir))); hdr->device = statbuf.st_dev; hdr->inode = statbuf.st_ino; /* * Initialize space allocation status for segment. */ hdr->totalsize = size; hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader)); /* Save info for possible future use */ UsedShmemSegAddr = memAddress; UsedShmemSegID = (unsigned long) NextShmemSegID; return hdr; }
/** * Performs the cleanup functions * * @param sharedMemPtr - the pointer to the shared memory */ void cleanUp(void** sharedMemPtr) { // this one only needs to detach from the shared mem, because recv will // handle all the dealloc procedures printf("Detaching from shared memory\n"); shmdt(sharedMemPtr); }
/** * this routine performs a test that indicates whether or not sysv shared * memory can safely be used during this run. * note: that we want to run this test as few times as possible. * * @return OPAL_SUCCESS when sysv can safely be used. */ static int sysv_runtime_query(mca_base_module_t **module, int *priority, const char *hint) { char c = 'j'; int shmid = -1; char *a = NULL; char *addr = NULL; struct shmid_ds tmp_buff; *priority = 0; *module = NULL; /* if hint isn't null, then someone else already figured out who is the * best runnable component is AND the caller is relaying that info so we * don't have to perform a run-time query. */ if (NULL != hint) { OPAL_OUTPUT_VERBOSE( (70, opal_shmem_base_framework.framework_output, "shmem: sysv: runtime_query: " "attempting to use runtime hint (%s)\n", hint) ); /* was i selected? if so, then we are done. * otherwise, disqualify myself. */ if (0 == strcasecmp(hint, mca_shmem_sysv_component.super.base_version.mca_component_name)) { *priority = mca_shmem_sysv_component.priority; *module = (mca_base_module_t *)&opal_shmem_sysv_module.super; return OPAL_SUCCESS; } else { *priority = 0; *module = NULL; return OPAL_SUCCESS; } } /* if we are here, then let the run-time test games begin */ OPAL_OUTPUT_VERBOSE( (70, opal_shmem_base_framework.framework_output, "shmem: sysv: runtime_query: NO HINT PROVIDED:" "starting run-time test...\n") ); if (-1 == (shmid = shmget(IPC_PRIVATE, (size_t)(opal_getpagesize()), IPC_CREAT | IPC_EXCL | S_IRWXU ))) { goto out; } else if ((void *)-1 == (addr = shmat(shmid, NULL, 0))) { goto out; } /* protect against lazy establishment - may not be needed, but can't hurt */ a = addr; *a = c; if (-1 == shmctl(shmid, IPC_RMID, NULL)) { goto out; } else if (-1 == shmctl(shmid, IPC_STAT, &tmp_buff)) { goto out; } /* all is well - rainbows and butterflies */ else { *priority = mca_shmem_sysv_component.priority; *module = (mca_base_module_t *)&opal_shmem_sysv_module.super; } out: if ((char *)-1 != addr) { shmdt(addr); } return OPAL_SUCCESS; }
void nk_DisconnClientStatuslink(void) { if(shmdt(shared_memory) == -1){ warn("remove memory link failed for Client Status Info\n"); } }
int main(void) { signed int *X; pid_t pid1, pid2; int shmid, i, status; struct sembuf pop, vop ; int semid1, semid2; semid1 = semget(IPC_PRIVATE, 1, 0777|IPC_CREAT); semid2 = semget(IPC_PRIVATE, 1, 0777|IPC_CREAT); semctl(semid1, 0, SETVAL, 0); semctl(semid2, 0, SETVAL, 1); pop.sem_num = vop.sem_num = 0; pop.sem_flg = vop.sem_flg = 0; pop.sem_op = -1 ; vop.sem_op = 1 ; shmid = shmget(IPC_PRIVATE, 1*sizeof(signed int), 0777|IPC_CREAT); X = (signed int *)shmat(shmid, 0, 0); *X = 0; pid1 = fork(); pid2 = fork(); if(pid1 == 0 && pid2 != 0) { P(semid1); for( i = 0; i < 10; i++) { *X += 1; if( i == 4 ) sleep(1); printf("\nIncrementing"); } shmdt(X); V(semid2); return 0; } if(pid2 == 0 && pid1 != 0) { P(semid2); for( i = 0; i < 10; i++) { *X -= 1; printf("\nDecrementing"); } shmdt(X); V(semid1); return 0; } if(pid1 == 0 && pid2 == 0) return 0; for( i = 0; i < 3; i++) wait(&status); printf("\nValue of X = %d\n", *X); shmdt(X); shmctl(shmid, IPC_RMID, 0); semctl(semid1, 0, IPC_RMID, 0); semctl(semid2, 0, IPC_RMID, 0); return 0; }
void eliminarMemoria() { shmdt (memoria); shmctl (memory_id , IPC_RMID, (struct shmid_ds *)NULL); }
void mexFunction (int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[]) { key_t key; ACQ_MessagePacketType *packet; int msgNumber, msgType, msgId, sampleNumber, numSamples, numChannels, *data; int shmid, shmsize; int numValues = 28160; shmsize = sizeof(ACQ_MessagePacketType) * ACQ_MSGQ_SIZE; /* make the key if ((key = ftok(ACQ_MSGQ_SHMPATH, ACQ_MSGQ_SHMPROJID)) == -1) { perror("ftok"); exit(1); } */ /* use the pre-defined key */ key = ACQ_MSGQ_SHMKEY; /* connect to (and possibly create) the segment */ if ((shmid = shmget(key, shmsize, 0644 | IPC_CREAT )) == -1) mexErrMsgTxt("shmget"); /* attach to the segment to get a pointer to it */ packet = shmat(shmid, (void *)0, 0); if ((char *)packet == (char *)(-1)) mexErrMsgTxt("shmat"); if (nrhs<7) mexErrMsgTxt("Not enough input arguments"); msgNumber = (int)mxGetScalar(prhs[0])-1; /* one offset in Matlab, zero offset in C */ /* msgType = (int)mxGetScalar(prhs[1]); msgId = (int)mxGetScalar(prhs[2]); sampleNumber = (int)mxGetScalar(prhs[3]); numSamples = (int)mxGetScalar(prhs[4]); numChannels = (int)mxGetScalar(prhs[5]); */ if (mxGetClassID(prhs[6]) != mxINT32_CLASS) mexErrMsgTxt("Invalid type of data, should be int32"); if (msgNumber<0) mexErrMsgTxt("Cannot write before the first packet"); if (msgNumber>=ACQ_MSGQ_SIZE) mexErrMsgTxt("Cannot write after the last packet"); numValues = mxGetNumberOfElements(prhs[6]); numValues = ( numValues>28160 ? 28160 : numValues ); /* check boundary */ numValues = ( numValues<0 ? 0 : numValues ); /* check boundary */ /* write the meta-information to the packet */ packet[msgNumber].message_type = (int)mxGetScalar(prhs[1]); packet[msgNumber].messageId = (int)mxGetScalar(prhs[2]); packet[msgNumber].sampleNumber = (int)mxGetScalar(prhs[3]); packet[msgNumber].numSamples = (int)mxGetScalar(prhs[4]); packet[msgNumber].numChannels = (int)mxGetScalar(prhs[5]); /* write the data to the packet */ memcpy(packet[msgNumber].data, mxGetData(prhs[6]), numValues*sizeof(int)); /* detach from the segment */ if (shmdt(packet) == -1) mexErrMsgTxt("shmdt"); } /* end of mexFunction */
void testaccess_ipc (int ipc_id, char opt, int mode, int expected, char *outbuf) { int actual, semval, rc; int myerror = 0; char *chPtr; struct sembuf sop; uid_t tmpuid; gid_t tmpgid; struct msqbuf { long mtype; char mtext[80]; } s_message, r_message; /* If we are root, we expect to succeed event * without explicit permission. */ strcat (outbuf, (expected == -1) ? "expected: fail " : "expected: pass "); switch (opt) { /* Shared Memory */ case 'm': /* Try to get (mode) access * There is no notion of a write-only shared memory * segment. We are testing READ ONLY and READWRITE access. */ chPtr = shmat (ipc_id, NULL, (mode == O_RDONLY) ? SHM_RDONLY : 0); if (chPtr != (void *) -1) { strcat (outbuf, "actual: pass "); actual = 0; if (shmdt (chPtr) == -1) { perror ("Warning: Could not dettach memory segment"); } } else { myerror = errno; strcat (outbuf, "actual: fail "); actual = -1; } break; /* Semaphores */ case 's': tmpuid = geteuid (); tmpgid = getegid (); semval = semctl (ipc_id, 0, GETVAL); /* Need semaphore value == 0 to execute read permission test */ if ((mode == O_RDONLY) && (semval > 0)) { setids (0, 0); if ((semctl (ipc_id, 0, SETVAL, 0)) == -1) { printf ("Unable to set semaphore value: %d\n", errno); } setids (tmpuid, tmpgid); } /* Try to get mode access */ sop.sem_num = 0; sop.sem_op = mode; sop.sem_flg = SEM_UNDO; actual = semop (ipc_id, &sop, 1); myerror = errno; if (actual != -1) { strcat (outbuf, "actual: pass "); /* back to semaphore original value */ if (mode != O_RDONLY) { sop.sem_op = -1;/* decrement semaphore */ rc = semop (ipc_id, &sop, 1); } } else { /* Back to semaphore original value */ if ((mode == O_RDONLY) && (semval > 0)) { setids (0, 0); if ((semctl (ipc_id, 0, SETVAL, semval)) == -1) { printf ("Unable to set semaphore " "value: %d\n", errno); } setids (tmpuid, tmpgid); } strcat (outbuf, "actual: fail "); } break; /* Message Queues */ case 'q': tmpuid = geteuid (); tmpgid = getegid (); if (mode == O_RDONLY) { setids (0, 0); /* Send a message to test msgrcv function */ s_message.mtype = 1; memset (s_message.mtext, '\0', sizeof (s_message.mtext)); strcpy (s_message.mtext, "First Message\0"); if ((rc = msgsnd (ipc_id, &s_message, strlen (s_message.mtext), 0)) == -1) { printf ("Error sending first message: %d\n", errno); } setids (tmpuid, tmpgid); } s_message.mtype = 1; memset (s_message.mtext, '\0', sizeof (s_message.mtext)); strcpy (s_message.mtext, "Write Test\0"); /* Try to get WRITE access */ if (mode == O_WRONLY) { actual = msgsnd (ipc_id, &s_message, strlen (s_message.mtext), 0); } else { /* Try to get READ access */ actual = msgrcv (ipc_id, &r_message, sizeof (r_message.mtext), 0, IPC_NOWAIT); } myerror = errno; if (actual != -1) { strcat (outbuf, "actual: pass "); } else { strcat (outbuf, "actual: fail "); } if (((mode == O_RDONLY) && (actual == -1)) || ((mode == O_WRONLY) && (actual != -1))) { setids (0, 0); /* discard the message send */ rc = msgrcv (ipc_id, &r_message, sizeof (r_message.mtext), 0, IPC_NOWAIT); setids (tmpuid, tmpgid); } break; } if ((actual == expected) || ((expected == 0) && (actual != -1))) { strcat (outbuf, "\tresult: PASS\n"); totalpass++; } else { errno = myerror;// restore errno from correct error code sprintf (&(outbuf[strlen (outbuf)]), "\tresult: FAIL : " "errno = %d\n", errno); totalfail++; } printf ("%s", outbuf); return; }
/** * Processing callback */ static void Demux (void *opaque) { demux_t *demux = opaque; demux_sys_t *sys = demux->p_sys; xcb_connection_t *conn = sys->conn; /* Determine capture region */ xcb_get_geometry_cookie_t gc; xcb_query_pointer_cookie_t qc; gc = xcb_get_geometry (conn, sys->window); if (sys->follow_mouse) qc = xcb_query_pointer (conn, sys->window); xcb_get_geometry_reply_t *geo = xcb_get_geometry_reply (conn, gc, NULL); if (geo == NULL) { msg_Err (demux, "bad X11 drawable 0x%08"PRIx32, sys->window); discard: if (sys->follow_mouse) xcb_discard_reply (conn, gc.sequence); return; } int w = sys->w; int h = sys->h; int x, y; if (sys->follow_mouse) { xcb_query_pointer_reply_t *ptr = xcb_query_pointer_reply (conn, qc, NULL); if (ptr == NULL) { free (geo); return; } if (w == 0 || w > geo->width) w = geo->width; x = ptr->win_x; if (x < w / 2) x = 0; else if (x >= (int)geo->width - (w / 2)) x = geo->width - w; else x -= w / 2; if (h == 0 || h > geo->height) h = geo->height; y = ptr->win_y; if (y < h / 2) y = 0; else if (y >= (int)geo->height - (h / 2)) y = geo->height - h; else y -= h / 2; } else { int max; x = sys->x; max = (int)geo->width - x; if (max <= 0) goto discard; if (w == 0 || w > max) w = max; y = sys->y; max = (int)geo->height - y; if (max <= 0) goto discard; if (h == 0 || h > max) h = max; } /* Update elementary stream format (if needed) */ if (w != sys->cur_w || h != sys->cur_h) { if (sys->es != NULL) es_out_Del (demux->out, sys->es); /* Update composite pixmap */ if (sys->window != geo->root) { xcb_free_pixmap (conn, sys->pixmap); /* no-op first time */ xcb_composite_name_window_pixmap (conn, sys->window, sys->pixmap); xcb_create_pixmap (conn, geo->depth, sys->pixmap, geo->root, geo->width, geo->height); } sys->es = InitES (demux, w, h, geo->depth, &sys->bpp); if (sys->es != NULL) { sys->cur_w = w; sys->cur_h = h; sys->bpp /= 8; /* bits -> bytes */ } } /* Capture screen */ xcb_drawable_t drawable = (sys->window != geo->root) ? sys->pixmap : sys->window; free (geo); block_t *block = NULL; #if HAVE_SYS_SHM_H if (sys->shm) { /* Capture screen through shared memory */ size_t size = w * h * sys->bpp; int id = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777); if (id == -1) /* XXX: fallback */ { msg_Err (demux, "shared memory allocation error: %m"); goto noshm; } /* Attach the segment to X and capture */ xcb_shm_get_image_reply_t *img; xcb_shm_get_image_cookie_t ck; xcb_shm_attach (conn, sys->segment, id, 0 /* read/write */); ck = xcb_shm_get_image (conn, drawable, x, y, w, h, ~0, XCB_IMAGE_FORMAT_Z_PIXMAP, sys->segment, 0); xcb_shm_detach (conn, sys->segment); img = xcb_shm_get_image_reply (conn, ck, NULL); xcb_flush (conn); /* ensure eventual detach */ if (img == NULL) { shmctl (id, IPC_RMID, 0); goto noshm; } free (img); /* Attach the segment to VLC */ void *shm = shmat (id, NULL, 0 /* read/write */); shmctl (id, IPC_RMID, 0); if (-1 == (intptr_t)shm) { msg_Err (demux, "shared memory attachment error: %m"); return; } block = block_shm_Alloc (shm, size); if (unlikely(block == NULL)) shmdt (shm); } noshm: #endif if (block == NULL) { /* Capture screen through socket (fallback) */ xcb_get_image_reply_t *img; img = xcb_get_image_reply (conn, xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, drawable, x, y, w, h, ~0), NULL); if (img == NULL) return; uint8_t *data = xcb_get_image_data (img); size_t datalen = xcb_get_image_data_length (img); block = block_heap_Alloc (img, data + datalen - (uint8_t *)img); if (block == NULL) return; block->p_buffer = data; block->i_buffer = datalen; } /* Send block - zero copy */ if (sys->es != NULL) { block->i_pts = block->i_dts = mdate (); es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts); es_out_Send (demux->out, sys->es, block); } }
static void IpcMemoryDetach(int status, Datum shmaddr) { if (shmdt(DatumGetPointer(shmaddr)) < 0) elog(LOG, "shmdt(%p) failed: %m", DatumGetPointer(shmaddr)); }
void nk_DisconnIPInfolink(void) { if(shmdt(shared_memory3) == -1){ warn("remove memory link failed for IP Info\n"); } }
/* * PGSharedMemoryIsInUse * * Is a previously-existing shmem segment still existing and in use? * * The point of this exercise is to detect the case where a prior postmaster * crashed, but it left child backends that are still running. Therefore * we only care about shmem segments that are associated with the intended * DataDir. This is an important consideration since accidental matches of * shmem segment IDs are reasonably common. */ bool PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2) { IpcMemoryId shmId = (IpcMemoryId) id2; struct shmid_ds shmStat; struct stat statbuf; PGShmemHeader *hdr; /* * We detect whether a shared memory segment is in use by seeing whether * it (a) exists and (b) has any processes attached to it. */ if (shmctl(shmId, IPC_STAT, &shmStat) < 0) { /* * EINVAL actually has multiple possible causes documented in the * shmctl man page, but we assume it must mean the segment no longer * exists. */ if (errno == EINVAL) return false; /* * EACCES implies that the segment belongs to some other userid, which * means it is not a Postgres shmem segment (or at least, not one that * is relevant to our data directory). */ if (errno == EACCES) return false; /* * Some Linux kernel versions (in fact, all of them as of July 2007) * sometimes return EIDRM when EINVAL is correct. The Linux kernel * actually does not have any internal state that would justify * returning EIDRM, so we can get away with assuming that EIDRM is * equivalent to EINVAL on that platform. */ #ifdef HAVE_LINUX_EIDRM_BUG if (errno == EIDRM) return false; #endif /* * Otherwise, we had better assume that the segment is in use. The * only likely case is EIDRM, which implies that the segment has been * IPC_RMID'd but there are still processes attached to it. */ return true; } /* If it has no attached processes, it's not in use */ if (shmStat.shm_nattch == 0) return false; /* * Try to attach to the segment and see if it matches our data directory. * This avoids shmid-conflict problems on machines that are running * several postmasters under the same userid. */ if (stat(DataDir, &statbuf) < 0) return true; /* if can't stat, be conservative */ hdr = (PGShmemHeader *) shmat(shmId, NULL, PG_SHMAT_FLAGS); if (hdr == (PGShmemHeader *) -1) return true; /* if can't attach, be conservative */ if (hdr->magic != PGShmemMagic || hdr->device != statbuf.st_dev || hdr->inode != statbuf.st_ino) { /* * It's either not a Postgres segment, or not one for my data * directory. In either case it poses no threat. */ shmdt((void *) hdr); return false; } /* Trouble --- looks a lot like there's still live backends */ shmdt((void *) hdr); return true; }
void nk_DisconnServerInfolink(void) { if(shmdt(shared_memory4) == -1){ warn("remove memory link failed for Server Info Info\n"); } }
/* ////////////////////////////////////////////////////////////////////////// */ static int sysv_runtime_query(mca_base_module_t **module, int *priority, const char *hint) { char c = 'j'; int shmid = -1; char *a = NULL; char *addr = NULL; struct shmid_ds tmp_buff; int flags; int ret; ret = OSHMEM_SUCCESS; *priority = 0; *module = NULL; /* if we are here, then let the run-time test games begin */ #if defined (SHM_HUGETLB) if (mca_sshmem_sysv_component.use_hp != 0) { flags = IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | SHM_HUGETLB; if (-1 == (shmid = shmget(IPC_PRIVATE, sshmem_sysv_gethugepagesize(), flags))) { if (mca_sshmem_sysv_component.use_hp == 1) { mca_sshmem_sysv_component.use_hp = 0; ret = OSHMEM_ERR_NOT_AVAILABLE; goto out; } mca_sshmem_sysv_component.use_hp = 0; } else if ((void *)-1 == (addr = shmat(shmid, NULL, 0))) { shmctl(shmid, IPC_RMID, NULL); if (mca_sshmem_sysv_component.use_hp == 1) { mca_sshmem_sysv_component.use_hp = 0; ret = OSHMEM_ERR_NOT_AVAILABLE; goto out; } mca_sshmem_sysv_component.use_hp = 0; } } #else if (mca_sshmem_sysv_component.use_hp == 1) { mca_sshmem_sysv_component.use_hp = 0; ret = OSHMEM_ERR_NOT_AVAILABLE; goto out; } mca_sshmem_sysv_component.use_hp = 0; #endif if (0 == mca_sshmem_sysv_component.use_hp) { flags = IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR; if (-1 == (shmid = shmget(IPC_PRIVATE, (size_t)(opal_getpagesize()), flags))) { ret = OSHMEM_ERR_NOT_AVAILABLE; goto out; } else if ((void *)-1 == (addr = shmat(shmid, NULL, 0))) { shmctl(shmid, IPC_RMID, NULL); ret = OSHMEM_ERR_NOT_AVAILABLE; goto out; } } /* protect against lazy establishment - may not be needed, but can't hurt */ a = addr; *a = c; if (-1 == shmctl(shmid, IPC_RMID, NULL)) { goto out; } else if (-1 == shmctl(shmid, IPC_STAT, &tmp_buff)) { goto out; } /* all is well - rainbows and butterflies */ else { *priority = mca_sshmem_sysv_component.priority; *module = (mca_base_module_t *)&mca_sshmem_sysv_module.super; } out: if ((char *)-1 != addr) { shmdt(addr); } return ret; }
int main(int argc, char *argv[]) { int value = 0; key_t key = ftok(".", 0xFF); int sem_id = semget(key, 1, IPC_CREAT|0644); if(-1 == sem_id) { perror("semget"); exit(EXIT_FAILURE); } if(-1 == (semctl(sem_id, 0, SETVAL, value))) { perror("semctl"); exit(EXIT_FAILURE); } //creat the shared memory(1K bytes) int shm_id = shmget(key, 1024, IPC_CREAT|0644); if(-1 == shm_id) { perror("shmget"); exit(EXIT_FAILURE); } //attach the shm_id to this process char *shm_ptr = (char*)shmat(shm_id, NULL, 0); if(NULL == shm_ptr) { perror("shmat"); exit(EXIT_FAILURE); } struct sembuf sem_b; sem_b.sem_num = 0; //first sem(index=0) sem_b.sem_flg = SEM_UNDO; sem_b.sem_op = -1; //decrease 1,make sem=0 printf("\nMessage receiver is running:\n"); while(1) { if(1 == (value = semctl(sem_id, 0, GETVAL))) { printf("\tThe message is : %s\n", shm_ptr); if(-1 == semop(sem_id, &sem_b, 1)) { perror("semop"); exit(EXIT_FAILURE); } } if(0 == (strcmp(shm_ptr ,"exit"))) { printf("\nExit receiver process now!\n"); break; } } shmdt(shm_ptr); //delete the shared memory if(-1 == shmctl(shm_id, IPC_RMID, NULL)) { perror("shmctl"); exit(EXIT_FAILURE); } //delete the semaphore if(-1 == semctl(sem_id, 0, IPC_RMID)) { perror("semctl"); exit(EXIT_FAILURE); } return 0; }
int main(int argc, char *argv[]) { time_t t0 = time(NULL); if (argc > 2) { printf("Usage\n\n"); printf("%s -c\ncleanup ipc\n\n", argv[0]); printf("%s -s\nsetup ipc\n\n", argv[0]); printf("%s < inputfile\ncout file, show accumulated output\n\n", argv[0]); printf("%s name < inputfile\ncout file, show output with name\n\n", argv[0]); exit(1); } int retcode = 0; create_if_missing(REF_FILE, S_IRUSR | S_IWUSR); key_t shm_key = ftok(REF_FILE, 1); if (shm_key < 0) { handle_error(-1, "ftok failed", PROCESS_EXIT); } if (argc == 2 && strcmp(argv[1], "-s") == 0) { printf("setting up IPC\n"); create_shm(shm_key, "create", "shmget failed", IPC_CREAT | IPC_EXCL); create_sem(1, "sem_open failed", O_CREAT | O_EXCL); printf("done\n"); exit(0); } int shm_id = create_shm(shm_key, "create", "shmget failed", 0); sem_t *sem_ptr = create_sem(1, "semget failed", 0); if (argc == 2 && strcmp(argv[1], "-c") == 0) { printf("cleaning up IPC\n"); cleanup(shm_id, sem_ptr); exit(0); } char *name = ""; if (argc == 2) { name = argv[1]; } struct data *shm_data = (struct data *) shmat(shm_id, NULL, 0); char buffer[BUF_SIZE]; struct data local_data; long *counter = local_data.counter; for (int i = 0; i < ALPHA_SIZE; i++) { counter[i] = 0L; } while (TRUE) { ssize_t size_read = read(STDIN_FILENO, buffer, BUF_SIZE); if (size_read == 0) { /* end of file */ break; } handle_error(size_read, "error while reading stdin", PROCESS_EXIT); int i; for (i = 0; i < size_read; i++) { unsigned char c = buffer[i]; counter[c]++; } } unsigned int i; time_t t1 = time(NULL); retcode = sem_wait(sem_ptr); handle_error(retcode, "error while getting semaphore", PROCESS_EXIT); time_t dt = time(NULL) - t1; for (int i = 0; i < ALPHA_SIZE; i++) { long *tcounter = shm_data->counter; long *scounter = local_data.counter; tcounter[i] += scounter[i]; } time_t total = time(NULL) - t0; printf("------------------------------------------------------------\n"); printf("%s: pid=%ld\n", name, (long) getpid()); printf("total time for calculation: ~ %ld sec; total wait for semaphore: ~ %ld sec\n", (long) total, (long) dt); printf("------------------------------------------------------------\n"); for (i = 0; i < ALPHA_SIZE; i++) { long *counter = shm_data->counter; long val = counter[i]; if (! (i & 007)) { printf("\n"); fflush(stdout); } if ((i & 0177) < 32 || i == 127) { printf("\\%03o: %10ld ", i, val); } else { printf("%4c: %10ld ", (char) i, val); } } printf("\n\n"); printf("------------------------------------------------------------\n\n"); fflush(stdout); retcode = sem_post(sem_ptr); handle_error(retcode, "error while releasing semaphore", PROCESS_EXIT); retcode = sem_close(sem_ptr); handle_error(retcode, "error while closing semaphore", PROCESS_EXIT); retcode = shmdt(shm_data); handle_error(retcode, "error while detaching shared memory", PROCESS_EXIT); /* cleanup(); */ printf("done\n"); exit(0); }
int main(int argc,char* argv[]){ if(argc>1){ if(strcmp(argv[1],"-h")==0){ help(argv[0]); } exit(EXIT_SUCCESS); } struct shared_use_st *shared_stuff; void *shared_memory = (void *)0; int shmid=0; sem_t * sem_id; pid_t child; sem_id=sem_open("mysemaph", O_CREAT, 0600, 1); if(sem_id == SEM_FAILED) { perror("parent sem_open"); return; } shmid = shmget( (key_t)1234,sizeof(struct shared_use_st),0666 |IPC_CREAT ); if(shmid==-1){ perror("shmget: shmget failed"); exit(EXIT_FAILURE); } shared_memory = shmat(shmid,(void *)0, 0); if (shared_memory == (void *)-1) { perror("shmat failed"); exit(EXIT_FAILURE); } shared_stuff = (struct shared_use_st *)shared_memory; sem_wait(sem_id); shared_stuff->noOfProcess++; sem_post(sem_id); if((child=fork())==-1){ perror("fork error"); exit(EXIT_FAILURE); } else if(child==0){ readFromShared(shared_stuff,sem_id); } else{ writeToShared(shared_stuff,sem_id); kill(child,SIGKILL); } sem_wait(sem_id); shared_stuff->noOfProcess--; int num_process=shared_stuff->noOfProcess; sem_post(sem_id); if (shmdt(shared_memory) == -1) { perror("shmdt failed"); exit(EXIT_FAILURE); } if(num_process==0){ if (shmctl(shmid, IPC_RMID, 0) == -1) { perror("shmctl error"); exit(EXIT_FAILURE); } } exit(EXIT_SUCCESS); }
static void getMyXImage(void) { #ifdef HAVE_SHM if (mLocalDisplay && XShmQueryExtension(mDisplay)) Shmem_Flag = 1; else { Shmem_Flag = 0; mp_msg(MSGT_VO, MSGL_WARN, "Shared memory not supported\nReverting to normal Xlib\n"); } if (Shmem_Flag) CompletionType = XShmGetEventBase(mDisplay) + ShmCompletion; if (Shmem_Flag) { myximage = XShmCreateImage(mDisplay, vinfo.visual, depth, ZPixmap, NULL, &Shminfo[0], image_width, image_height); if (myximage == NULL) { mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling ( Ximage error )\n"); goto shmemerror; } Shminfo[0].shmid = shmget(IPC_PRIVATE, myximage->bytes_per_line * myximage->height, IPC_CREAT | 0777); if (Shminfo[0].shmid < 0) { XDestroyImage(myximage); mp_msg(MSGT_VO, MSGL_V, "%s\n", strerror(errno)); //perror( strerror( errno ) ); mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling ( seg id error )\n"); goto shmemerror; } Shminfo[0].shmaddr = (char *) shmat(Shminfo[0].shmid, 0, 0); if (Shminfo[0].shmaddr == ((char *) -1)) { XDestroyImage(myximage); if (Shminfo[0].shmaddr != ((char *) -1)) shmdt(Shminfo[0].shmaddr); mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling ( address error )\n"); goto shmemerror; } myximage->data = Shminfo[0].shmaddr; ImageData = (unsigned char *) myximage->data; Shminfo[0].readOnly = False; XShmAttach(mDisplay, &Shminfo[0]); XSync(mDisplay, False); if (gXErrorFlag) { XDestroyImage(myximage); shmdt(Shminfo[0].shmaddr); mp_msg(MSGT_VO, MSGL_WARN, "Shared memory error,disabling.\n"); gXErrorFlag = 0; goto shmemerror; } else shmctl(Shminfo[0].shmid, IPC_RMID, 0); { static int firstTime = 1; if (firstTime) { mp_msg(MSGT_VO, MSGL_V, "Sharing memory.\n"); firstTime = 0; } } } else { shmemerror: Shmem_Flag = 0; #endif myximage = XCreateImage(mDisplay, vinfo.visual, depth, ZPixmap, 0, NULL, image_width, image_height, 8, 0); ImageDataOrig = malloc(myximage->bytes_per_line * image_height + 32); myximage->data = ImageDataOrig + 16 - ((long)ImageDataOrig & 15); memset(myximage->data, 0, myximage->bytes_per_line * image_height); ImageData = myximage->data; #ifdef HAVE_SHM } #endif }
int main() { char *cp=NULL; int pid, pid1, shmid; int status; key = (key_t)getpid() ; sigemptyset(&sigset); sigaddset(&sigset,SIGUSR1); sigprocmask(SIG_BLOCK,&sigset,NULL); pid = fork(); switch (pid) { case -1: tst_resm(TBROK,"fork failed"); tst_exit() ; case 0: child(); } /*------------------------------------------------------*/ if ((shmid = shmget(key, SIZE, IPC_CREAT|0666)) < 0) { perror("shmget"); tst_resm(TFAIL,"Error: shmget: shmid = %d, errno = %d\n", shmid, errno) ; /* * kill the child if parent failed to do the attach */ (void)kill(pid, SIGINT); } else { #ifdef __ia64__ cp = (char *) shmat(shmid, ADDR_IA, 0); #elif defined(__ARM_ARCH_4T__) cp = (char *) shmat(shmid, (void*) NULL, 0); #elif defined(__mips__) cp = (char *) shmat(shmid, ADDR_MIPS, 0); #else cp = (char *) shmat(shmid, ADDR, 0); #endif if (cp == (char *)-1) { perror("shmat") ; tst_resm(TFAIL, "Error: shmat: shmid = %d, errno = %d\n", shmid, errno) ; /* kill the child if parent failed to do the attch */ kill(pid, SIGINT) ; /* remove shared memory segment */ rm_shm(shmid) ; tst_exit() ; } *cp = 'A'; *(cp+1) = 'B'; *(cp+2) = 'C'; kill(pid, SIGUSR1); while ( (pid1 = wait(&status)) < 0 && (errno == EINTR) ) ; if (pid1 != pid) { tst_resm(TFAIL,"Waited on the wrong child") ; tst_resm(TFAIL, "Error: wait_status = %d, pid1= %d\n", status, pid1) ; } } tst_resm(TPASS,"shmget,shmat"); /*---------------------------------------------------------------*/ if (shmdt(cp) < 0) { tst_resm(TFAIL,"shmdt"); } tst_resm(TPASS,"shmdt"); /*-------------------------------------------------------------*/ rm_shm(shmid) ; tst_exit() ; /*-----------------------------------------------------------*/ return(0); }
HwDbgInfo_debug hsail_init_hwdbginfo(HsailNotificationPayload* payload) { struct ui_out *uiout = NULL; /* pointer to shared memory*/ void* pShm = NULL; /* HwDbgFacilities objects */ HwDbgInfo_err errout_twolevel= HWDBGINFO_E_UNEXPECTED; HwDbgInfo_err errout_onelevel= HWDBGINFO_E_UNEXPECTED; HwDbgInfo_debug dbg_op = NULL; const int max_shared_mem_size = hsail_get_agent_binary_shmem_max_size(); if (payload == NULL) { /* return the cached dbgInfo there exists */ return gs_DbgInfo; } gdb_assert(payload->m_Notification == HSAIL_NOTIFY_NEW_BINARY); uiout = current_uiout; /* Shared memory buffer pointer*/ dbg_op = NULL; if(hsail_is_debug_facilities_loaded()) { /* A copy of the shared memory segment )*/ void* dbe_binary = NULL; size_t dbe_binary_size = 0; int shmid = -1; hsail_segment_update_loadmap(); /*1M used is hard wired for now*/ shmid = shmget(hsail_get_agent_binary_shmem_key(), max_shared_mem_size, 0666); if (shmid <= 0) { ui_out_text(uiout, "GDB: HwDbgFacilities init: shmid is invalid\n"); } gdb_assert(shmid > 0); /* Get shm pointer */ pShm = (int*)shmat(shmid, NULL, 0); if (pShm == NULL) { ui_out_text(uiout, "GDB: HwDbgFacilities init: pShm is NULL\n"); } gdb_assert(pShm != NULL); dbe_binary_size = ((size_t*)pShm)[0]; gdb_assert(dbe_binary_size > 0 && dbe_binary_size < max_shared_mem_size); dbe_binary = xmalloc(dbe_binary_size); gdb_assert(dbe_binary != NULL); memcpy(dbe_binary,(size_t*)pShm+1,dbe_binary_size); /* Uncomment this call if you need to save the binary to the file hsail_breakpoint_save_binary_to_file(dbe_binary_size, dbe_binary); */ /* Attempt to initialize as a HSAIL backend binary*/ dbg_op = hwdbginfo_init_with_hsa_1_0_binary(dbe_binary, dbe_binary_size, &errout_twolevel); /* Keep this printf here as a reminder for a * quick way to check that the IPC happened correctly*/ /* int i = 0; for(i = 0; i<10;i++) { printf("%d \t %d\n",i,*((int*)dbe_binary + i)); } */ /* If we get a no HL binary, return code, we try to initialize as a single level binary */ if (errout_twolevel == HWDBGINFO_E_NOHLBINARY) { /* dbg_op = hwdbginfo_init_with_single_level_binary(dbe_binary, dbe_binary_size, &errout_onelevel); */ dbg_op = NULL; } /* * In the near future, debug facilities needs to be able to tell the difference * between an incomplete 2 level code object and a complete 1 level code object. * Since we dont support debugging LC for 1.3, this is not a big issue. * */ /* If we have a single level binary, thats good, we dont need to check the * two level return code */ if (errout_twolevel == HWDBGINFO_E_NOHLBINARY && errout_onelevel == HWDBGINFO_E_SUCCESS) { fflush(stdout); } else if (errout_twolevel != HWDBGINFO_E_SUCCESS ) { /* HwDbgFacilities init: Called DebugFacilities Incorrectly. * We can add more detailed messages such as low-level dwarf or high level dwarf missing in the future * */ ui_out_text(uiout, "[ROCm-gdb]: The code object for the current dispatch does not contain debug information\n"); fflush(stdout); dbg_op = NULL; } /* Test function to print all the mapped addresses and line numbers */ /* hsail_dbginfo_test_all_mapped_addrs(dbg_op); */ /* We can clear the dbe_binary buffer once we have initialized HWDbgFacilities */ if (dbe_binary != NULL) { free_current_contents(&dbe_binary); } /* Get the kernel source, only if the 2 level initialization was good*/ if (errout_twolevel == HWDBGINFO_E_SUCCESS) { if (!hsail_dbginfo_init_source_buffer(dbg_op)) { ui_out_text(uiout, "[ROCm-gdb]: HwDbgFacilities get hsail text error\n"); } } /* Detach shared memory */ if (shmdt(pShm) == -1) { ui_out_text(uiout, "GDB: HwDbgFacilities init: Error detaching shm\n"); } } /* cache the dgbInfo */ gs_DbgInfo = dbg_op; return gs_DbgInfo; /* * This function's caller will use the returned context to query the * Debug Facilities API */ }
int main ( void ) // Mode d'emploi : // Gère la création et la destruction de tous les composantes de // l'application, et tourne tant que le simulateur n'a pas renvoyé. // // Contrat : // (Aucun) // // Algorithme : // Initialise les composantes fournies pour le TP, puis crée tous les // mécanismes IPC (sémaphores, files de message et la mémoire partagée). // Chaque tâche est ensuite lancée une par une, le simulateur étant // lancé en dernier pour éviter que l'utilisateur lance des demandes // avant que toute l'application ne soit prête. // La tâche tourne ensuite à l'infini tant que le simulateur ne renvoie // pas, avant de demander la terminaison de chaque tâche en cours puis // la suppression des mécanismes IPC. Finalement, l'affichage est // terminé et l'application termine. // { /* --- Initialisation --- */ // Initialisation de l'application #ifdef AFFICHAGE_XTERM enum TypeTerminal terminal = XTERM; #else // AFFICHAGE_XTERM enum TypeTerminal terminal = VT220; #endif // AFFICHAGE_XTERM InitialiserApplication(terminal); size_t MAX_TACHES = NB_BARRIERES + 2; pid_t tachesPid[MAX_TACHES]; size_t taches = 0; // Initialiser les files de message int filesId[NB_BARRIERES]; for (size_t i = 0; i < NB_BARRIERES; i++) { filesId[i] = msgget(CLE_BARRIERES[i], IPC_CREAT | DROITS); } // Initialiser le sémaphore du mutex à 1 (car il n'est pas en cours // d'utilisation) et les sémaphores des barrières à 0 (car il n'y a aucune // requête en cours). int semId = semget(CLE_SEMAPHORE, NUM_SEMAPHORES, IPC_CREAT | DROITS); semctl(semId, SEM_MUTEX, SETVAL, 1); semctl(semId, SEM_PBP, SETVAL, 0); semctl(semId, SEM_ABP, SETVAL, 0); semctl(semId, SEM_EGB, SETVAL, 0); // Initialiser la mémoire partagée avec aucune place occupée et aucune // requête envoyée int shmId = shmget(CLE_MEMOIRE_PARTAGEE, sizeof(memoire_partagee_t), IPC_CREAT | DROITS); memoire_partagee_t * mem = (memoire_partagee_t *) shmat(shmId, NULL, 0); mem->placesOccupees = 0; for (size_t i = 0; i < NB_PLACES; i++) { mem->places[i] = PLACE_VIDE; } for (size_t i = 0; i < NB_BARRIERES_ENTREE; i++) { mem->requetes[i] = REQUETE_VIDE; } shmdt(mem); // Lancer toutes les tâches tachesPid[taches++] = ActiverHeure(); if ((tachesPid[taches++] = fork()) == 0) { // Fils - Barrière S (Sortie) BarriereSortie(SORTIE_GASTON_BERGER); } else { // Père if ((tachesPid[taches++] = fork()) == 0) { // Fils - Barrière Entrée (Blaise Pascal - Profs) BarriereEntree(PROF_BLAISE_PASCAL); } else { // Père if ((tachesPid[taches++] = fork()) == 0) { // Fils - Barrière Entrée (Blaise Pascal - Autres) BarriereEntree(AUTRE_BLAISE_PASCAL); } else { // Père if ((tachesPid[taches++] = fork()) == 0) { // Fils - Barrière Entrée (Gaston Berger) BarriereEntree(ENTREE_GASTON_BERGER); } else { // Père if ((tachesPid[taches++] = fork()) == 0) { // Fils - Simulateur Simulateur(); } else { // Père /* --- Moteur --- */ waitpid(tachesPid[--taches], NULL, 0); /* --- Destruction --- */ while (taches) { kill(tachesPid[--taches], SIGUSR2); } semctl(semId, 0, IPC_RMID, NULL); shmctl(shmId, IPC_RMID, NULL); for (size_t i = 0; i < NB_BARRIERES; i++) { msgctl(filesId[i], IPC_RMID, NULL); } TerminerApplication(true); exit(0); } } } } } return 0; }
int free_shared_mem(void *data, int id) { shmdt(data); return shmctl(id, IPC_RMID, 0); }
int main(int argc,char* argv[]) { int shmid; int proj_id; key_t key; int shm_size; char* shm_addr,*addr; pid_t pid; if(argc!=3){ printf("Usage: %s shared_memory_size info\n",argv[0]); return 1; } shm_size=atoi(argv[1]); proj_id=2; key=ftok("/home/program",proj_id); if(key==-1){ perror("cannot generate the IPC key"); return 1; } shmid=shmget(key,shm_size,IPC_CREAT | 0660); if(shmid==-1){ perror("cannot create a shared memory segment"); return 1; } addr=(char*)shmat(shmid,NULL,0); shm_addr=addr; if(shm_addr==(char*)(-1)){ perror("cannot attach the shared memory to process"); return 1; } printf("====address information===\n"); printf("etext address: %x\n",&etext); printf("edata address: %x\n",&edata); printf("end address: %x\n",&end); printf("shared memory segment address: %x\n",shm_addr); printf("==========================\n"); strcpy(shm_addr,argv[2]); printf("the input string is : %s\n",argv[2]); printf("before fork,in shared memory segment the string is: %s\n",shm_addr); pid=fork(); if(pid==-1){ perror("cannot create new process"); return 1; }else if(pid==0){ printf("in child process, the string is %s \n",shm_addr); printf("modify the content in shared memory\n"); *shm_addr +=1; _exit(0); }else{ wait(NULL); printf("after fork, in shared memory segment the string is %s\n",shm_addr); if(shmdt(shm_addr)==-1){ perror("cannot release the memory"); return 1; } if(shmctl(shmid,IPC_RMID,NULL)==-1){ perror("cannot delete existing shared memory segment"); return 1; } } return 0; }
int main (void) { int i; int allocateOK; ximg = NULL; d = XOpenDisplay (NULL); if (!d) fputs ("Couldn't open display\n", stderr), exit (1); screen = DefaultScreen (d); gc = DefaultGC (d, screen); /* Find a visual */ vis.screen = screen; vlist = XGetVisualInfo (d, VisualScreenMask, &vis, &match); if (!vlist) fputs ("No matched visuals\n", stderr), exit (1); vis = vlist[0]; XFree (vlist); // That's not a fair comparison colormap_size is depth in bits! // if (vis.colormap_size < COLORS) // printf("Colormap is too small: %i.\n",vis.colormap_size); // , exit (1); // printf("Colour depth: %i\n",vis.colormap_size); // No way this number means nothing! It is 64 for 16-bit truecolour and 256 for 8-bit! win = XCreateSimpleWindow (d, DefaultRootWindow (d), 0, 0, WIN_W, WIN_H, 0, WhitePixel (d, screen), BlackPixel (d, screen)); int xclass=get_xvisinfo_class(vis); // printf("class = %i\n",xclass); stylee = ( vis.depth > 8 ? styleeTrueColor : styleePrivate ); // printf("stylee=%i\n",stylee); if ( get_xvisinfo_class(vis) % 2 == 1) { /* The odd numbers can redefine colors */ // printf("%i\n",get_xvisinfo_class(vis)); colormap = DefaultColormap (d, screen); Visual *defaultVisual=DefaultVisual(d,screen); /* Allocate cells */ allocateOK = (XAllocColorCells (d, colormap, 1, NULL, 0, color, COLORS) != 0); printf("Allocated OK? %i\n",allocateOK); if (allocateOK) { // printf("Allocated OK\n"); // This doesn't work for installed colormap! /* Modify the colorcells */ for (i = 0; i < COLORS; i++) xrgb[i].pixel = color[i]; XStoreColors (d, colormap, xrgb, COLORS); } else { colormap = XCreateColormap(d,win,defaultVisual,AllocNone); // redocolors(); } // black = XBlackPixel(d,screen); // white = XWhitePixel(d,screen); XAllocColorCells(d,colormap,1,0,0,color,colors); XSetWindowColormap(d,win,colormap); } else if ( get_xvisinfo_class(vis) == TrueColor) { colormap = DefaultColormap (d, screen); // printf("TrueColor %i = %i\n",xclass,TrueColor); /* This will lookup the color and sets the xrgb[i].pixel value */ // for (i = 0; i < COLORS; i++) // XAllocColor (d, colormap, &xrgb[i]); } else fprintf (stderr, "Not content with visual class %d.\n", get_xvisinfo_class(vis) ), exit (1); /* Find out if MITSHM is supported and useable */ printf ("MITSHM: "); if (XShmQueryVersion (d, &mitshm_major_code, &mitshm_minor_code, &shared_pixmaps)) { int (*handler) (Display *, XErrorEvent *); ximg = XShmCreateImage (d, vis.visual, vis.depth, XShmPixmapFormat (d), NULL, &shminfo, WIN_W, WIN_H); shminfo.shmid = shmget (IPC_PRIVATE, ximg->bytes_per_line * ximg->height, IPC_CREAT | 0777); shminfo.shmaddr = (char *)shmat (shminfo.shmid, 0, 0); ximg->data = (char *)shminfo.shmaddr; handler = XSetErrorHandler (mitshm_handler); XShmAttach (d, &shminfo); /* Tell the server to attach */ XSync (d, 0); XSetErrorHandler (handler); shmctl (shminfo.shmid, IPC_RMID, 0); /* Mark this shm segment for deletion at once. The segment will * automatically become released when both the server and this * client have detached from it. * (Process termination automagically detach shm segments) */ if (!can_use_mitshm) { shmdt (shminfo.shmaddr); ximg = NULL; } } if (ximg == NULL) { can_use_mitshm = 0; /* XInitImage(ximg); */ ximg = XCreateImage (d, vis.visual, vis.depth, ZPixmap, 0, (char *)malloc (WIN_W * WIN_H), WIN_W, WIN_H, 8, 0); } if (can_use_mitshm) printf ("YES!\n"); else printf ("NO, using fallback instead.\n"); // DrawFractal (ximg,xrgb); XSelectInput (d, win, ButtonPressMask | ExposureMask); XMapWindow (d, win); real_main(); // XNextEvent (d, &ev); // switch (ev.type) { // case ButtonPress: // should_quit = 1; // break; // case Expose: // if (can_use_mitshm) // XShmPutImage (d, win, gc, img, 0, 0, 0, 0, WIN_W, WIN_H, True); // else // XPutImage (d, win, gc, img, 0, 0, 0, 0, WIN_W, WIN_H); // break; // default: // break; // } if (get_xvisinfo_class(vis) % 2 == 1 || get_xvisinfo_class(vis) == TrueColor) { unsigned long color[COLORS]; if (allocateOK) { for (i = 0; i < COLORS; i++) color[i] = xrgb[i].pixel; XFreeColors (d, colormap, color, COLORS, 0); } /* Allocated colors freed */ } else { XUninstallColormap (d, colormap); } if (can_use_mitshm) { XShmDetach (d, &shminfo); /* Server detached */ XDestroyImage (ximg); /* Image struct freed */ shmdt (shminfo.shmaddr); /* We're detached */ } else XDestroyImage (ximg); /* Image struct freed */ XDestroyWindow (d, win); /* Window removed */ XCloseDisplay (d); /* Display disconnected */ /* So you can see how your computer compares to your friend's */ getrusage (RUSAGE_SELF, &resource_utilization); float seconds=(float)resource_utilization.ru_utime.tv_sec +(float)resource_utilization.ru_utime.tv_usec*0.000000001; printf("CPU seconds per frame: %f\n",seconds/(float)frameno); // printf ("CPU seconds consumed: %ds and %dµs\n", // (int) resource_utilization.ru_utime.tv_sec, // (int) resource_utilization.ru_utime.tv_usec); return 0; }
int svlWindowManagerX11::DoModal(bool show, bool fullscreen) { Destroy(); DestroyFlag = false; unsigned int i, atom_count; int x, y, prevright, prevbottom; unsigned int lastimage = 0; unsigned long black, white; XSizeHints wsh; #if CISST_SVL_HAS_XV Atom atoms[3]; unsigned int xvadaptorcount; XvAdaptorInfo *xvai; XVisualInfo xvvinfo; bool xvupdateimage = true; #else // CISST_SVL_HAS_XV Atom atoms[2]; #endif // CISST_SVL_HAS_XV // setting decoration hints for borderless mode struct { unsigned long flags; unsigned long functions; unsigned long decorations; signed long input_mode; unsigned long status; } mwm; mwm.flags = MWM_HINTS_DECORATIONS; mwm.decorations = 0; mwm.functions = 0; mwm.input_mode = 0; mwm.status = 0; // resetting DestroyedSignal event if (DestroyedSignal) delete(DestroyedSignal); DestroyedSignal = new osaThreadSignal(); if (DestroyedSignal == 0) goto labError; // initialize display and pick default screen xDisplay = XOpenDisplay(reinterpret_cast<char*>(0)); xScreen = DefaultScreen(xDisplay); #if CISST_SVL_HAS_XV // check if 24bpp is suppoted by the display if (XMatchVisualInfo(xDisplay, xScreen, 24, TrueColor, &xvvinfo) == 0) goto labError; #endif // CISST_SVL_HAS_XV // pick colors black = BlackPixel(xDisplay, xScreen); white = WhitePixel(xDisplay, xScreen); // create windows xWindows = new Window[NumOfWins]; memset(xWindows, 0, NumOfWins * sizeof(Window)); xGCs = new GC[NumOfWins]; memset(xGCs, 0, NumOfWins * sizeof(GC)); // create atoms for overriding default window behaviours atoms[0] = XInternAtom(xDisplay, "WM_DELETE_WINDOW", False); atoms[1] = XInternAtom(xDisplay, "_MOTIF_WM_HINTS", False); #if CISST_SVL_HAS_XV atoms[2] = XInternAtom(xDisplay, "XV_SYNC_TO_VBLANK", False); #endif // CISST_SVL_HAS_XV // create title strings Titles = new std::string[NumOfWins]; CustomTitles = new std::string[NumOfWins]; CustomTitleEnabled = new int[NumOfWins]; #if CISST_SVL_HAS_XV xvImg = new XvImage*[NumOfWins]; xvShmInfo = new XShmSegmentInfo[NumOfWins]; xvPort = new XvPortID[NumOfWins]; if (xvImg == 0 || xvShmInfo == 0 || xvPort == 0) goto labError; memset(xvImg, 0, NumOfWins * sizeof(XvImage*)); memset(xvShmInfo, 0, NumOfWins * sizeof(XShmSegmentInfo)); memset(xvPort, 0, NumOfWins * sizeof(XvPortID)); #else // CISST_SVL_HAS_XV // create images xImageBuffers = new unsigned char*[NumOfWins]; for (i = 0; i < NumOfWins; i ++) { xImageBuffers[i] = new unsigned char[Width[i] * Height[i] * 4]; } xImg = new XImage*[NumOfWins]; memset(xImg, 0, NumOfWins * sizeof(XImage*)); if (xImg == 0) goto labError; for (i = 0; i < NumOfWins; i ++) { xImg[i] = XCreateImage(xDisplay, DefaultVisual(xDisplay, xScreen), 24, ZPixmap, 0, reinterpret_cast<char*>(xImageBuffers[i]), Width[i], Height[i], 32, 0); } #endif // CISST_SVL_HAS_XV prevright = prevbottom = 0; for (i = 0; i < NumOfWins; i ++) { if (PosX == 0 || PosY == 0) { if (fullscreen) { x = prevright; y = 0; prevright += Width[i]; } else { x = prevright; y = prevbottom; prevright += 50; prevbottom += 50; } } else { x = PosX[i]; y = PosY[i]; } xWindows[i] = XCreateSimpleWindow(xDisplay, DefaultRootWindow(xDisplay), x, y, Width[i], Height[i], 0, black, white); if (xWindows[i] == 0) goto labError; // overriding default behaviours: // - borderless mode // - closing window if (fullscreen) { XChangeProperty(xDisplay, xWindows[i], atoms[1], atoms[1], 32, PropModeReplace, reinterpret_cast<unsigned char*>(&mwm), 5); atom_count = 2; } else { atom_count = 1; } XSetWMProtocols(xDisplay, xWindows[i], atoms, atom_count); wsh.flags = PPosition|PSize; wsh.x = x; wsh.y = y; wsh.width = Width[i]; wsh.height = Height[i]; XSetNormalHints(xDisplay, xWindows[i], &wsh); // set window title CustomTitleEnabled[i] = 0; std::ostringstream ostring; if (Title.length() > 0) { if (NumOfWins > 0) ostring << Title << " #" << i; else ostring << Title; } else { if (NumOfWins > 0) ostring << Title << "svlImageWindow #" << i; else ostring << "svlImageWindow"; } Titles[i] = ostring.str(); XSetStandardProperties(xDisplay, xWindows[i], Titles[i].c_str(), Titles[i].c_str(), None, NULL, 0, NULL); // set even mask XSelectInput(xDisplay, xWindows[i], ExposureMask|PointerMotionMask|ButtonPressMask|KeyPressMask); // set window colormap XSetWindowColormap(xDisplay, xWindows[i], DefaultColormapOfScreen(DefaultScreenOfDisplay(xDisplay))); #if CISST_SVL_HAS_XV // query shared memory extension if (!XShmQueryExtension(xDisplay)) goto labError; // query video adaptors if (XvQueryAdaptors(xDisplay, DefaultRootWindow(xDisplay), &xvadaptorcount, &xvai) != Success) goto labError; xvPort[i] = xvai->base_id + i; XvFreeAdaptorInfo(xvai); // overriding default Xvideo vertical sync behavior XvSetPortAttribute (xDisplay, xvPort[i], atoms[2], 1); #endif // CISST_SVL_HAS_XV // create graphics context xGCs[i] = XCreateGC(xDisplay, xWindows[i], 0, 0); // set default colors XSetBackground(xDisplay, xGCs[i], white); XSetForeground(xDisplay, xGCs[i], black); #if CISST_SVL_HAS_XV // create image in shared memory xvImg[i] = XvShmCreateImage(xDisplay, xvPort[i], 0x32595559/*YUV2*/, 0, Width[i], Height[i], &(xvShmInfo[i])); if (xvImg[i]->width < static_cast<int>(Width[i]) || xvImg[i]->height < static_cast<int>(Height[i])) { CMN_LOG_INIT_ERROR << "DoModal - image too large for XV to display (requested=" << Width[i] << "x" << Height[i] << "; allowed=" << xvImg[i]->width << "x" << xvImg[i]->height << ")" << std::endl; goto labError; } xvShmInfo[i].shmid = shmget(IPC_PRIVATE, xvImg[i]->data_size, IPC_CREAT | 0777); xvShmInfo[i].shmaddr = xvImg[i]->data = reinterpret_cast<char*>(shmat(xvShmInfo[i].shmid, 0, 0)); xvShmInfo[i].readOnly = False; if (!XShmAttach(xDisplay, &(xvShmInfo[i]))) goto labError; #endif // CISST_SVL_HAS_XV // clear window XClearWindow(xDisplay, xWindows[i]); // show window if requested if (show) XMapRaised(xDisplay, xWindows[i]); } // signal that initialization is done if (InitReadySignal) InitReadySignal->Raise(); // main message loop XEvent event; KeySym code; unsigned int winid; while (1) { osaSleep(0.001); #if CISST_SVL_HAS_XV if (!xvupdateimage) { for (int events = XPending(xDisplay); events > 0; events --) { #else // CISST_SVL_HAS_XV if (XPending(xDisplay)) { #endif // CISST_SVL_HAS_XV XNextEvent(xDisplay, &event); // find recipient for (winid = 0; winid < NumOfWins; winid ++) { if (event.xany.window == xWindows[winid]) break; } if (winid == NumOfWins) continue; // override default window behaviour if (event.type == ClientMessage) { if (static_cast<unsigned long>(event.xclient.data.l[0]) == atoms[0]) { // X11 server wants to close window // Do nothing.... we will destroy it ourselves later } continue; } // window should be closed if (event.type == UnmapNotify) { printf("destroy\n"); if (xGCs[winid]) { XFreeGC(xDisplay, xGCs[winid]); xGCs[winid] = 0; } xWindows[winid] = 0; continue; } // window should be updated if (event.type == Expose && event.xexpose.count == 0) { XClearWindow(xDisplay, xWindows[winid]); continue; } if (event.type == KeyPress) { code = XLookupKeysym(&event.xkey, 0); if (code >= 48 && code <= 57) { // ascii numbers OnUserEvent(winid, true, code); continue; } if (code >= 97 && code <= 122) { // ascii letters OnUserEvent(winid, true, code); continue; } if (code == 13 || code == 32) { // special characters with correct ascii code OnUserEvent(winid, true, code); continue; } if (code >= 0xffbe && code <= 0xffc9) { // F1-F12 OnUserEvent(winid, false, winInput_KEY_F1 + (code - 0xffbe)); continue; } switch (code) { case 0xFF55: OnUserEvent(winid, false, winInput_KEY_PAGEUP); break; case 0xFF56: OnUserEvent(winid, false, winInput_KEY_PAGEDOWN); break; case 0xFF50: OnUserEvent(winid, false, winInput_KEY_HOME); break; case 0xFF57: OnUserEvent(winid, false, winInput_KEY_END); break; case 0xFF63: OnUserEvent(winid, false, winInput_KEY_INSERT); break; case 0xFFFF: OnUserEvent(winid, false, winInput_KEY_DELETE); break; case 0xFF51: OnUserEvent(winid, false, winInput_KEY_LEFT); break; case 0xFF53: OnUserEvent(winid, false, winInput_KEY_RIGHT); break; case 0xFF52: OnUserEvent(winid, false, winInput_KEY_UP); break; case 0xFF54: OnUserEvent(winid, false, winInput_KEY_DOWN); break; } continue; } if (event.type == ButtonPress) { if (event.xbutton.button == Button1) { if (!LButtonDown && !RButtonDown) { LButtonDown = true; XGrabPointer(xDisplay, xWindows[winid], false, PointerMotionMask|ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); } OnUserEvent(winid, false, winInput_LBUTTONDOWN); } else if (event.xbutton.button == Button3) { if (!LButtonDown && !RButtonDown) { RButtonDown = true; XGrabPointer(xDisplay, xWindows[winid], false, PointerMotionMask|ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); } OnUserEvent(winid, false, winInput_RBUTTONDOWN); } } if (event.type == ButtonRelease) { if (event.xbutton.button == Button1) { OnUserEvent(winid, false, winInput_LBUTTONUP); if (LButtonDown && !RButtonDown) { LButtonDown = false; XUngrabPointer(xDisplay, CurrentTime); } } else if (event.xbutton.button == Button3) { OnUserEvent(winid, false, winInput_RBUTTONUP); if (!LButtonDown && RButtonDown) { RButtonDown = false; XUngrabPointer(xDisplay, CurrentTime); } } } if (event.type == MotionNotify) { SetMousePos(static_cast<short>(event.xmotion.x), static_cast<short>(event.xmotion.y)); OnUserEvent(winid, false, winInput_MOUSEMOVE); } #if CISST_SVL_HAS_XV // image update complete if (event.type == XShmGetEventBase(xDisplay) + ShmCompletion) { xvupdateimage = true; continue; } } if (!xvupdateimage) signalImage.Wait(0.01); #endif // CISST_SVL_HAS_XV } else { if (DestroyFlag) break; if (ImageCounter > lastimage) { csImage.Enter(); lastimage = ImageCounter; #if CISST_SVL_HAS_XV for (i = 0; i < NumOfWins; i ++) { XvShmPutImage(xDisplay, xvPort[i], xWindows[i], xGCs[i], xvImg[i], 0, 0, Width[i], Height[i], 0, 0, Width[i], Height[i], True); } xvupdateimage = false; #else // CISST_SVL_HAS_XV for (i = 0; i < NumOfWins; i ++) { xImg[i]->data = reinterpret_cast<char*>(xImageBuffers[i]); XPutImage(xDisplay, xWindows[i], xGCs[i], xImg[i], 0, 0, 0, 0, Width[i], Height[i]); } #endif // CISST_SVL_HAS_XV /* for (i = 0; i < NumOfWins; i ++) { if (CustomTitleEnabled[i] < 0) { // Restore original timestamp XSetStandardProperties(xDisplay, xWindows[i], Titles[i].c_str(), Titles[i].c_str(), None, NULL, 0, NULL); } else if (CustomTitleEnabled[i] > 0) { // Set custom timestamp XSetStandardProperties(xDisplay, xWindows[i], CustomTitles[i].c_str(), CustomTitles[i].c_str(), None, NULL, 0, NULL); } } */ csImage.Leave(); } } } labError: #if CISST_SVL_HAS_XV if (xvShmInfo) { for (i = 0; i < NumOfWins; i ++) { XShmDetach(xDisplay, &(xvShmInfo[i])); shmdt(xvShmInfo[i].shmaddr); } delete [] xvShmInfo; xvShmInfo = 0; } #endif // CISST_SVL_HAS_XV XSync(xDisplay, 0); for (i = 0; i < NumOfWins; i ++) { if (xGCs[i]) XFreeGC(xDisplay, xGCs[i]); if (xWindows[i]) XDestroyWindow(xDisplay, xWindows[i]); } XCloseDisplay(xDisplay); #if CISST_SVL_HAS_XV if (xvImg) { for (i = 0; i < NumOfWins; i ++) { if (xvImg[i]) XFree(xvImg[i]); } delete [] xvImg; xvImg = 0; } if (xvPort) { delete [] xvPort; xvPort = 0; } #else // CISST_SVL_HAS_XV if (xImg) { for (i = 0; i < NumOfWins; i ++) { if (xImg[i]) XDestroyImage(xImg[i]); } delete [] xImg; xImg = 0; } if (xImageBuffers) { delete [] xImageBuffers; xImageBuffers = 0; } #endif // CISST_SVL_HAS_XV if (xGCs) { delete [] xGCs; xGCs = 0; } if (xWindows) { delete [] xWindows; xWindows = 0; } if (Titles) { delete [] Titles; Titles = 0; } if (CustomTitles) { delete [] CustomTitles; CustomTitles = 0; } if (CustomTitleEnabled) { delete [] CustomTitleEnabled; CustomTitleEnabled = 0; } xScreen = 0; xDisplay = 0; if (DestroyedSignal) DestroyedSignal->Raise(); return 0; }