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