Join shm_pair.info and .segment of Windows shm implementation

There is not much point in having two distinct file mappings; since the
info mapping is very small and of fixed size, we can put it at the
beginning of a single mapping.  Besides the obvious resource savings,
that also simplifies the error handling.

Closes GH-8648.
This commit is contained in:
Christoph M. Becker 2022-05-27 23:16:11 +02:00
parent e9e3a1481b
commit d7bdc040b4
No known key found for this signature in database
GPG Key ID: D66C9593118BCCB6
2 changed files with 12 additions and 29 deletions

View File

@ -69,10 +69,8 @@ static void tsrm_win32_dtor(tsrm_win32_globals *globals)
if (globals->shm) {
for (ptr = globals->shm; ptr < (globals->shm + globals->shm_size); ptr++) {
UnmapViewOfFile(ptr->addr);
CloseHandle(ptr->segment);
UnmapViewOfFile(ptr->descriptor);
CloseHandle(ptr->info);
CloseHandle(ptr->segment);
}
free(globals->shm);
}
@ -610,26 +608,27 @@ TSRM_API int pclose(FILE *stream)
}/*}}}*/
#define SEGMENT_PREFIX "TSRM_SHM_SEGMENT:"
#define DESCRIPTOR_PREFIX "TSRM_SHM_DESCRIPTOR:"
#define INT_MIN_AS_STRING "-2147483648"
TSRM_API int shmget(key_t key, size_t size, int flags)
{/*{{{*/
shm_pair *shm;
char shm_segment[sizeof(SEGMENT_PREFIX INT_MIN_AS_STRING)], shm_info[sizeof(DESCRIPTOR_PREFIX INT_MIN_AS_STRING)];
char shm_segment[sizeof(SEGMENT_PREFIX INT_MIN_AS_STRING)];
HANDLE shm_handle = NULL, info_handle = NULL;
BOOL created = FALSE;
if (key != IPC_PRIVATE) {
snprintf(shm_segment, sizeof(shm_segment), SEGMENT_PREFIX "%d", key);
snprintf(shm_info, sizeof(shm_info), DESCRIPTOR_PREFIX "%d", key);
shm_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment);
info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info);
}
if (!shm_handle && !info_handle) {
if (!shm_handle) {
if (flags & IPC_CREAT) {
if (size > SIZE_MAX - sizeof(shm->descriptor)) {
return -1;
}
size += sizeof(shm->descriptor);
#if SIZEOF_SIZE_T == 8
DWORD high = size >> 32;
DWORD low = (DWORD)size;
@ -638,26 +637,14 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
DWORD low = size;
#endif
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, high, low, key == IPC_PRIVATE ? NULL : shm_segment);
info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), key == IPC_PRIVATE ? NULL : shm_info);
created = TRUE;
}
if (!shm_handle || !info_handle) {
if (shm_handle) {
CloseHandle(shm_handle);
}
if (info_handle) {
CloseHandle(info_handle);
}
if (!shm_handle) {
return -1;
}
} else {
if (flags & IPC_EXCL) {
if (shm_handle) {
CloseHandle(shm_handle);
}
if (info_handle) {
CloseHandle(info_handle);
}
CloseHandle(shm_handle);
return -1;
}
}
@ -665,12 +652,10 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
shm = shm_get(key, NULL);
if (!shm) {
CloseHandle(shm_handle);
CloseHandle(info_handle);
return -1;
}
shm->segment = shm_handle;
shm->info = info_handle;
shm->descriptor = MapViewOfFileEx(shm->info, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
shm->descriptor = MapViewOfFileEx(shm->segment, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
if (NULL != shm->descriptor && created) {
shm->descriptor->shm_perm.key = key;
@ -691,7 +676,6 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
CloseHandle(shm->segment);
}
UnmapViewOfFile(shm->descriptor);
CloseHandle(shm->info);
return -1;
}
@ -706,7 +690,7 @@ TSRM_API void *shmat(int key, const void *shmaddr, int flags)
return (void*)-1;
}
shm->addr = MapViewOfFileEx(shm->segment, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
shm->addr = shm->descriptor + sizeof(shm->descriptor);
if (NULL == shm->addr) {
int err = GetLastError();
@ -734,7 +718,7 @@ TSRM_API int shmdt(const void *shmaddr)
shm->descriptor->shm_lpid = getpid();
shm->descriptor->shm_nattch--;
ret = UnmapViewOfFile(shm->addr) ? 0 : -1;
ret = 1;
if (!ret && shm->descriptor->shm_nattch <= 0) {
ret = UnmapViewOfFile(shm->descriptor) ? 0 : -1;
shm->descriptor = NULL;

View File

@ -50,7 +50,6 @@ typedef struct {
typedef struct {
void *addr;
HANDLE info;
HANDLE segment;
struct shmid_ds *descriptor;
} shm_pair;