00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "subprocessWindowBuffer.h"
00016 #include <sys/mman.h>
00017 #include <fcntl.h>
00018 #include <string.h>
00019
00020 #include <iostream>
00021 using namespace std;
00022
00023 const char SubprocessWindowBuffer::
00024 _magic_number[SubprocessWindowBuffer::magic_number_length] = "pNdaSWB";
00025
00026
00027
00028
00029
00030
00031
00032 void *SubprocessWindowBuffer::
00033 operator new(size_t, void *addr) {
00034 return addr;
00035 }
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 SubprocessWindowBuffer::
00046 SubprocessWindowBuffer(int x_size, int y_size) {
00047 memcpy(_this_magic, _magic_number, magic_number_length);
00048 _x_size = x_size;
00049 _y_size = y_size;
00050 _row_size = _x_size * 4;
00051 _framebuffer_size = _row_size * y_size;
00052 _event_in = 0;
00053 _event_out = 0;
00054 _last_written = 0;
00055 _last_read = 0;
00056
00057 _mmap_size = sizeof(*this) + _framebuffer_size;
00058 }
00059
00060
00061
00062
00063
00064
00065 SubprocessWindowBuffer::
00066 SubprocessWindowBuffer(const SubprocessWindowBuffer ©) :
00067 _mmap_size(copy._mmap_size),
00068 _x_size(copy._x_size),
00069 _y_size(copy._y_size),
00070 _row_size(copy._row_size),
00071 _framebuffer_size(copy._framebuffer_size)
00072 {
00073 memcpy(_this_magic, _magic_number, magic_number_length);
00074 _event_in = 0;
00075 _event_out = 0;
00076 _last_written = 0;
00077 _last_read = 0;
00078 }
00079
00080
00081
00082
00083
00084
00085 SubprocessWindowBuffer::
00086 ~SubprocessWindowBuffer() {
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 SubprocessWindowBuffer *SubprocessWindowBuffer::
00107 new_buffer(int &fd, size_t &mmap_size, string &filename,
00108 int x_size, int y_size) {
00109 mmap_size = 0;
00110 fd = -1;
00111
00112 filename = tmpnam(NULL);
00113
00114 fd = open(filename.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600);
00115 if (fd == -1) {
00116 perror(filename.c_str());
00117 return NULL;
00118 }
00119
00120
00121 SubprocessWindowBuffer temp(x_size, y_size);
00122 mmap_size = temp._mmap_size;
00123
00124
00125 size_t zero_size = 1024;
00126 char zero[zero_size];
00127 memset(zero, 0, zero_size);
00128 for (size_t bi = 0; bi < mmap_size; bi += zero_size) {
00129 write(fd, zero, zero_size);
00130 }
00131
00132 void *shared_mem = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE,
00133 MAP_SHARED, fd, 0);
00134 if (shared_mem == (void *)-1) {
00135
00136 close(fd);
00137 fd = -1;
00138 mmap_size = 0;
00139 return NULL;
00140 }
00141
00142
00143 return new(shared_mem) SubprocessWindowBuffer(temp);
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 void SubprocessWindowBuffer::
00155 destroy_buffer(int fd, size_t mmap_size, const string &filename,
00156 SubprocessWindowBuffer *buffer) {
00157 buffer->~SubprocessWindowBuffer();
00158 close_buffer(fd, mmap_size, filename, buffer);
00159
00160
00161 unlink(filename.c_str());
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 SubprocessWindowBuffer *SubprocessWindowBuffer::
00180 open_buffer(int &fd, size_t &mmap_size, const string &filename) {
00181 mmap_size = 0;
00182
00183 fd = open(filename.c_str(), O_RDWR);
00184 if (fd == -1) {
00185 perror(filename.c_str());
00186 return NULL;
00187 }
00188
00189
00190 off_t file_size = lseek(fd, 0, SEEK_END);
00191 if (file_size < sizeof(SubprocessWindowBuffer)) {
00192 cerr << filename << " not large enough.\n";
00193 close(fd);
00194 fd = -1;
00195 return NULL;
00196 }
00197
00198
00199 size_t initial_size = sizeof(SubprocessWindowBuffer);
00200 void *shared_mem = mmap(NULL, initial_size, PROT_READ,
00201 MAP_SHARED, fd, 0);
00202 if (shared_mem == (void *)-1) {
00203 perror("mmap");
00204 cerr << "Couldn't map.\n";
00205 close(fd);
00206 fd = -1;
00207 return NULL;
00208 }
00209
00210 SubprocessWindowBuffer *temp = (SubprocessWindowBuffer *)shared_mem;
00211 if (!temp->verify_magic_number()) {
00212 cerr << "Not a subprocess window buffer: " << filename << "\n";
00213 munmap(shared_mem, initial_size);
00214 close(fd);
00215 fd = -1;
00216 return NULL;
00217 }
00218
00219
00220 mmap_size = temp->_mmap_size;
00221
00222
00223 munmap(shared_mem, initial_size);
00224
00225 if (file_size < mmap_size) {
00226 cerr << filename << " not large enough.\n";
00227 close(fd);
00228 fd = -1;
00229 return NULL;
00230 }
00231
00232 shared_mem = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE,
00233 MAP_SHARED, fd, 0);
00234 if (shared_mem == (void *)-1) {
00235 perror("mmap");
00236 cerr << "Couldn't map 2.\n";
00237 return NULL;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247 SubprocessWindowBuffer *buffer = (SubprocessWindowBuffer *)shared_mem;
00248 assert(buffer->_mmap_size == mmap_size);
00249 return buffer;
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 void SubprocessWindowBuffer::
00261 close_buffer(int fd, size_t mmap_size, const string &filename,
00262 SubprocessWindowBuffer *buffer) {
00263 munmap((void *)buffer, mmap_size);
00264 close(fd);
00265 }
00266
00267
00268
00269
00270
00271
00272
00273 bool SubprocessWindowBuffer::
00274 verify_magic_number() const {
00275 return (memcmp(_this_magic, _magic_number, magic_number_length) == 0);
00276 }