📄 shm.cc
字号:
return request.shmid ();}/*---------------------------------------------------------------------------* * client_shmmgr::fixup_shms_after_fork () * * The hFileMap handles are non-inheritable: so they have to be * re-acquired from cygserver. * * Nb. This routine need not be thread-safe as it is only called at startup. *---------------------------------------------------------------------------*/intclient_shmmgr::fixup_shms_after_fork (){ debug_printf ("re-attaching to shm segments: %d attached", _shmat_cnt); { int length = 0; for (segment_t *segptr = _segments_head; segptr; segptr = segptr->next) length += 1; if (_shmat_cnt != length) { system_printf (("state inconsistent: " "_shmat_cnt = %d, length of segments list = %d"), _shmat_cnt, length); return 1; } } for (segment_t *segptr = _segments_head; segptr; segptr = segptr->next) if (!attach (segptr->shmid, segptr->shmaddr, segptr->shmflg & ~SHM_RND, segptr->hFileMap)) { system_printf ("fatal error re-attaching to shm segment %d", segptr->shmid); return 1; } if (_shmat_cnt) debug_printf ("re-attached all %d shm segments", _shmat_cnt); return 0;}/*---------------------------------------------------------------------------* * client_shmmgr::client_shmmgr () *---------------------------------------------------------------------------*/client_shmmgr::client_shmmgr (){ InitializeCriticalSection (&_segments_lock);}/*---------------------------------------------------------------------------* * client_shmmgr::~client_shmmgr () *---------------------------------------------------------------------------*/client_shmmgr::~client_shmmgr (){ DeleteCriticalSection (&_segments_lock);}/*---------------------------------------------------------------------------* * client_shmmgr::find () *---------------------------------------------------------------------------*/client_shmmgr::segment_t *client_shmmgr::find (const void *const shmaddr, segment_t **previous){ if (previous) *previous = NULL; for (segment_t *segptr = _segments_head; segptr; segptr = segptr->next) if (segptr->shmaddr == shmaddr) return segptr; else if (segptr->shmaddr > shmaddr) // The list is sorted by shmaddr. return NULL; else if (previous) *previous = segptr; return NULL;}/*---------------------------------------------------------------------------* * client_shmmgr::attach () * * The body of shmat (), also used by fixup_shms_after_fork (). *---------------------------------------------------------------------------*/void *client_shmmgr::attach (const int shmid, const void *shmaddr, const int shmflg, HANDLE & hFileMap){ client_request_shm request (shmid, shmflg); if (request.make_request () == -1 || request.error_code ()) { syscall_printf (("-1 [%d] = " "shmat (shmid = %d, shmaddr = %p, shmflg = 0%o)"), request.error_code (), shmid, shmaddr, shmflg); set_errno (request.error_code ()); return NULL; } int result = 0; const DWORD access = (shmflg & SHM_RDONLY) ? FILE_MAP_READ : FILE_MAP_WRITE; if (shmaddr && (shmflg & SHM_RND)) shmaddr = (char *) shmaddr - ((ssize_t) shmaddr % SHMLBA); void *const ptr = MapViewOfFileEx (request.hFileMap (), access, 0, 0, 0, (void *) shmaddr); if (!ptr) { syscall_printf (("failed to map view " "[shmid = %d, handle = %p, shmaddr = %p]: %E"), shmid, request.hFileMap (), shmaddr); result = EINVAL; // FIXME } else if (shmaddr && ptr != shmaddr) { syscall_printf (("failed to map view at requested address " "[shmid = %d, handle = %p]: " "requested address = %p, mapped address = %p"), shmid, request.hFileMap (), shmaddr, ptr); result = EINVAL; // FIXME } if (result != 0) { if (!CloseHandle (request.hFileMap ())) syscall_printf (("failed to close file map handle " "[shmid = %d, handle = %p]: %E"), shmid, request.hFileMap ()); client_request_shm dt_req (shmid); if (dt_req.make_request () == -1 || dt_req.error_code ()) syscall_printf ("shmdt request failed [shmid = %d, handle = %p]: %s", shmid, request.hFileMap (), strerror (dt_req.error_code ())); set_errno (result); return NULL; } hFileMap = request.hFileMap (); return ptr;}/*---------------------------------------------------------------------------* * client_shmmgr::new_segment () * * Allocate a new segment for the given shmid, file map and address * and insert into the segment map. *---------------------------------------------------------------------------*/client_shmmgr::segment_t *client_shmmgr::new_segment (const int shmid, const void *const shmaddr, const int shmflg, const HANDLE hFileMap){ assert (ipc_ext2int_subsys (shmid) == IPC_SHMOP); assert (hFileMap); assert (shmaddr); segment_t *previous = NULL; // Insert pointer. const segment_t *const tmp = find (shmaddr, &previous); assert (!tmp); assert (previous \ ? (!previous->next || previous->next->shmaddr > shmaddr) \ : (!_segments_head || _segments_head->shmaddr > shmaddr)); segment_t *const segptr = safe_new (segment_t, shmid, shmaddr, shmflg, hFileMap); assert (segptr); if (previous) { segptr->next = previous->next; previous->next = segptr; } else { segptr->next = _segments_head; _segments_head = segptr; } const long cnt = InterlockedIncrement (&_shmat_cnt); assert (cnt > 0); return segptr;}/*---------------------------------------------------------------------------* * shmat () *---------------------------------------------------------------------------*/extern "C" void *shmat (const int shmid, const void *const shmaddr, const int shmflg){ sigframe thisframe (mainthread); return shmmgr.shmat (shmid, shmaddr, shmflg);}/*---------------------------------------------------------------------------* * shmctl () *---------------------------------------------------------------------------*/extern "C" intshmctl (const int shmid, const int cmd, struct shmid_ds *const buf){ sigframe thisframe (mainthread); return shmmgr.shmctl (shmid, cmd, buf);}/*---------------------------------------------------------------------------* * shmdt () *---------------------------------------------------------------------------*/extern "C" intshmdt (const void *const shmaddr){ sigframe thisframe (mainthread); return shmmgr.shmdt (shmaddr);}/*---------------------------------------------------------------------------* * shmget () *---------------------------------------------------------------------------*/extern "C" intshmget (const key_t key, const size_t size, const int shmflg){ sigframe thisframe (mainthread); return shmmgr.shmget (key, size, shmflg);}/*---------------------------------------------------------------------------* * fixup_shms_after_fork () *---------------------------------------------------------------------------*/int __stdcallfixup_shms_after_fork (){ return shmmgr.fixup_shms_after_fork ();}/*---------------------------------------------------------------------------* * client_request_shm::client_request_shm () *---------------------------------------------------------------------------*/client_request_shm::client_request_shm (const int shmid, const int shmflg) : client_request (CYGSERVER_REQUEST_SHM, &_parameters, sizeof (_parameters)){ _parameters.in.shmop = SHMOP_shmat; _parameters.in.shmid = shmid; _parameters.in.shmflg = shmflg; _parameters.in.cygpid = getpid (); _parameters.in.winpid = GetCurrentProcessId (); _parameters.in.uid = geteuid (); _parameters.in.gid = getegid (); msglen (sizeof (_parameters.in));}/*---------------------------------------------------------------------------* * client_request_shm::client_request_shm () *---------------------------------------------------------------------------*/client_request_shm::client_request_shm (const int shmid, const int cmd, const struct shmid_ds *const buf) : client_request (CYGSERVER_REQUEST_SHM, &_parameters, sizeof (_parameters)){ _parameters.in.shmop = SHMOP_shmctl; _parameters.in.shmid = shmid; _parameters.in.cmd = cmd; if (buf) _parameters.in.ds = *buf; _parameters.in.cygpid = getpid (); _parameters.in.winpid = GetCurrentProcessId (); _parameters.in.uid = geteuid (); _parameters.in.gid = getegid (); msglen (sizeof (_parameters.in));}/*---------------------------------------------------------------------------* * client_request_shm::client_request_shm () *---------------------------------------------------------------------------*/client_request_shm::client_request_shm (const int shmid) : client_request (CYGSERVER_REQUEST_SHM, &_parameters, sizeof (_parameters)){ _parameters.in.shmop = SHMOP_shmdt; _parameters.in.shmid = shmid; _parameters.in.cygpid = getpid (); _parameters.in.winpid = GetCurrentProcessId (); _parameters.in.uid = geteuid (); _parameters.in.gid = getegid (); msglen (sizeof (_parameters.in));}/*---------------------------------------------------------------------------* * client_request_shm::client_request_shm () *---------------------------------------------------------------------------*/client_request_shm::client_request_shm (const key_t key, const size_t size, const int shmflg) : client_request (CYGSERVER_REQUEST_SHM, &_parameters, sizeof (_parameters)){ _parameters.in.shmop = SHMOP_shmget; _parameters.in.key = key; _parameters.in.size = size; _parameters.in.shmflg = shmflg; _parameters.in.cygpid = getpid (); _parameters.in.winpid = GetCurrentProcessId (); _parameters.in.uid = geteuid (); _parameters.in.gid = getegid (); msglen (sizeof (_parameters.in));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -