1 /* vifm
2 * Copyright (C) 2018 xaizek.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include "shmem.h"
20
21 #include <windows.h>
22
23 #include <stddef.h> /* NULL */
24 #include <stdlib.h> /* malloc() free() */
25
26 #include "str.h"
27
28 /* Data of a single shmem instance. */
29 struct shmem_t
30 {
31 char *name; /* Name of this object as known to the system. */
32 HANDLE handle; /* File handle obtained from CreateFileMapping(). */
33 int created; /* This instance was created by us. */
34 void *ptr; /* The shared memory as an unstructured blob of bytes. */
35 size_t max_size; /* Maximum size of shared memory region. */
36 };
37
38 shmem_t *
shmem_create(const char name[],size_t initial_size,size_t max_size)39 shmem_create(const char name[], size_t initial_size, size_t max_size)
40 {
41 shmem_t *const shmem = malloc(sizeof(*shmem));
42 if(shmem == NULL)
43 {
44 return NULL;
45 }
46
47 shmem->name = format_str("Local\\%s-shmem", name);
48 if(shmem->name == NULL)
49 {
50 free(shmem);
51 return NULL;
52 }
53
54 shmem->ptr = NULL;
55 shmem->max_size = max_size;
56
57 shmem->handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
58 0, max_size, shmem->name);
59 if(shmem->handle == INVALID_HANDLE_VALUE)
60 {
61 free(shmem->name);
62 free(shmem);
63 return NULL;
64 }
65
66 shmem->created = (GetLastError() != ERROR_ALREADY_EXISTS);
67
68 shmem->ptr = MapViewOfFile(shmem->handle, FILE_MAP_ALL_ACCESS, 0, 0,
69 max_size);
70
71 if(shmem->ptr == NULL)
72 {
73 shmem_free(shmem);
74 return NULL;
75 }
76
77 return shmem;
78 }
79
80 void
shmem_destroy(shmem_t * shmem)81 shmem_destroy(shmem_t *shmem)
82 {
83 shmem_free(shmem);
84 }
85
86 void
shmem_free(shmem_t * shmem)87 shmem_free(shmem_t *shmem)
88 {
89 if(shmem == NULL)
90 {
91 return;
92 }
93
94 if(shmem->ptr != NULL)
95 {
96 UnmapViewOfFile(shmem->ptr);
97 }
98
99 CloseHandle(shmem->handle);
100 free(shmem->name);
101 free(shmem);
102 }
103
104 int
shmem_created_by_us(shmem_t * shmem)105 shmem_created_by_us(shmem_t *shmem)
106 {
107 return shmem->created;
108 }
109
110 void *
shmem_get_ptr(shmem_t * shmem)111 shmem_get_ptr(shmem_t *shmem)
112 {
113 return shmem->ptr;
114 }
115
116 int
shmem_resize(shmem_t * shmem,size_t new_size)117 shmem_resize(shmem_t *shmem, size_t new_size)
118 {
119 return (new_size <= shmem->max_size);
120 }
121
122 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
123 /* vim: set cinoptions+=t0 : */
124