VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/util/filenet.c@ 69989

Last change on this file since 69989 was 63199, checked in by vboxsync, 8 years ago

GuestHost/OpenGL: warnings (gcc).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.4 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include <stdlib.h>
8#include <stdio.h>
9#include <fcntl.h>
10#include <sys/stat.h>
11#ifdef WINDOWS
12#include <io.h>
13#else
14#include <unistd.h>
15#endif
16
17
18#include "cr_error.h"
19#include "cr_mem.h"
20#include "cr_string.h"
21#include "cr_bufpool.h"
22#include "cr_net.h"
23#include "cr_endian.h"
24#include "cr_threads.h"
25#include "net_internals.h"
26
27typedef enum {
28 CRFileMemory,
29 CRFileMemoryBig
30} CRFileBufferKind;
31
32#define CR_FILE_BUFFER_MAGIC 0x89134539
33
34#ifndef WINDOWS
35#define O_BINARY 0
36#endif
37
38typedef struct CRFileBuffer {
39 unsigned int magic;
40 CRFileBufferKind kind;
41 unsigned int len;
42 unsigned int allocated;
43 unsigned int pad;
44} CRFileBuffer;
45
46static struct {
47 int initialized;
48 int num_conns;
49 CRConnection **conns;
50 CRBufferPool *bufpool;
51#ifdef CHROMIUM_THREADSAFE
52 CRmutex mutex;
53#endif
54 CRNetReceiveFuncList *recv_list;
55 CRNetCloseFuncList *close_list;
56} cr_file;
57
58static void
59crFileReadExact( CRConnection *conn, void *buf, unsigned int len )
60{
61 char *dst = (char *) buf;
62
63 while ( len > 0 )
64 {
65 int num_read = read( conn->fd, buf, len );
66
67 if ( num_read < 0 )
68 {
69 crError( "Bad bad bad file error!" );
70 }
71 if (num_read == 0)
72 {
73 crError( "END OF FILE!" );
74 }
75
76 dst += num_read;
77 len -= num_read;
78 }
79}
80
81static void
82crFileWriteExact( CRConnection *conn, const void *buf, unsigned int len )
83{
84 int retval = write( conn->fd, buf, len );
85 if ( retval < (int) len )
86 {
87 crError( "crFileWriteExact: %s (tried to write %d bytes, actually wrote %d)", conn->filename, len, retval );
88 }
89}
90
91static void
92crFileAccept( CRConnection *conn, const char *hostname, unsigned short port )
93{
94 (void)hostname;
95 conn->file_direction = CR_FILE_READ;
96 conn->fd = open( conn->filename, O_RDONLY | O_BINARY );
97 if (conn->fd < 0)
98 {
99 crError( "Couldn't open %s for reading!", conn->filename );
100 }
101 (void) port;
102}
103
104static void
105*crFileAlloc( CRConnection *conn )
106{
107 CRFileBuffer *buf;
108
109#ifdef CHROMIUM_THREADSAFE
110 crLockMutex(&cr_file.mutex);
111#endif
112
113 buf = (CRFileBuffer *) crBufferPoolPop( cr_file.bufpool, conn->buffer_size );
114
115 if ( buf == NULL )
116 {
117 crDebug( "Buffer pool was empty, so I allocated %d bytes",
118 (int)(sizeof(CRFileBuffer) + conn->buffer_size) );
119 buf = (CRFileBuffer *)
120 crAlloc( sizeof(CRFileBuffer) + conn->buffer_size );
121 buf->magic = CR_FILE_BUFFER_MAGIC;
122 buf->kind = CRFileMemory;
123 buf->pad = 0;
124 buf->allocated = conn->buffer_size;
125 }
126
127#ifdef CHROMIUM_THREADSAFE
128 crUnlockMutex(&cr_file.mutex);
129#endif
130
131 return (void *)( buf + 1 );
132}
133
134static void
135crFileSingleRecv( CRConnection *conn, void *buf, unsigned int len )
136{
137 crFileReadExact( conn, buf, len );
138}
139
140static void
141crFileSend( CRConnection *conn, void **bufp, const void *start, unsigned int len )
142{
143 CRFileBuffer *file_buffer;
144 unsigned int *lenp;
145
146 if ( bufp == NULL )
147 {
148 /* we are doing synchronous sends from user memory, so no need
149 * to get fancy. Simply write the length & the payload and
150 * return. */
151 if (conn->swap)
152 {
153 len = SWAP32(len);
154 }
155 crFileWriteExact( conn, &len, sizeof(len) );
156 crFileWriteExact( conn, start, len );
157 return;
158 }
159
160 file_buffer = (CRFileBuffer *)(*bufp) - 1;
161
162 CRASSERT( file_buffer->magic == CR_FILE_BUFFER_MAGIC );
163
164 /* All of the buffers passed to the send function were allocated
165 * with crFileAlloc(), which includes a header with a 4 byte
166 * length field, to insure that we always have a place to write
167 * the length field, even when start == *bufp. */
168 lenp = (unsigned int *) start - 1;
169 *lenp = len;
170
171 crFileWriteExact(conn, lenp, len + sizeof(int) );
172
173 /* reclaim this pointer for reuse and try to keep the client from
174 accidentally reusing it directly */
175#ifdef CHROMIUM_THREADSAFE
176 crLockMutex(&cr_file.mutex);
177#endif
178 crBufferPoolPush( cr_file.bufpool, file_buffer, conn->buffer_size );
179#ifdef CHROMIUM_THREADSAFE
180 crUnlockMutex(&cr_file.mutex);
181#endif
182 *bufp = NULL;
183}
184
185static void
186crFileFree( CRConnection *conn, void *buf )
187{
188 CRFileBuffer *file_buffer = (CRFileBuffer *) buf - 1;
189
190 CRASSERT( file_buffer->magic == CR_FILE_BUFFER_MAGIC );
191 conn->recv_credits += file_buffer->len;
192
193 switch ( file_buffer->kind )
194 {
195 case CRFileMemory:
196#ifdef CHROMIUM_THREADSAFE
197 crLockMutex(&cr_file.mutex);
198#endif
199 crBufferPoolPush( cr_file.bufpool, file_buffer, conn->buffer_size );
200#ifdef CHROMIUM_THREADSAFE
201 crUnlockMutex(&cr_file.mutex);
202#endif
203 break;
204
205 case CRFileMemoryBig:
206 crFree( file_buffer );
207 break;
208
209 default:
210 crError( "Weird buffer kind trying to free in crFileFree: %d", file_buffer->kind );
211 }
212}
213
214int
215crFileRecv( void )
216{
217 CRMessage *msg;
218 int i;
219
220 if (!cr_file.num_conns)
221 {
222 return 0;
223 }
224 for ( i = 0; i < cr_file.num_conns; i++ )
225 {
226 CRFileBuffer *file_buffer;
227 unsigned int len;
228 CRConnection *conn = cr_file.conns[i];
229
230 crFileReadExact( conn, &len, sizeof( len ) );
231
232 CRASSERT( len > 0 );
233
234 if ( len <= conn->buffer_size )
235 {
236 file_buffer = (CRFileBuffer *) crFileAlloc( conn ) - 1;
237 }
238 else
239 {
240 file_buffer = (CRFileBuffer *)
241 crAlloc( sizeof(*file_buffer) + len );
242 file_buffer->magic = CR_FILE_BUFFER_MAGIC;
243 file_buffer->kind = CRFileMemoryBig;
244 file_buffer->pad = 0;
245 }
246
247 file_buffer->len = len;
248
249 crFileReadExact( conn, file_buffer + 1, len );
250
251 conn->recv_credits -= len;
252
253 msg = (CRMessage *) (file_buffer + 1);
254 crNetDispatchMessage( cr_file.recv_list, conn, msg, len );
255
256 /* CR_MESSAGE_OPCODES is freed in
257 * crserverlib/server_stream.c
258 *
259 * OOB messages are the programmer's problem. -- Humper 12/17/01 */
260 if (msg->header.type != CR_MESSAGE_OPCODES && msg->header.type != CR_MESSAGE_OOB)
261 {
262 crFileFree( conn, file_buffer + 1 );
263 }
264 }
265
266 return 1;
267}
268
269static void
270crFileHandleNewMessage( CRConnection *conn, CRMessage *msg,
271 unsigned int len )
272{
273 CRFileBuffer *buf = ((CRFileBuffer *) msg) - 1;
274
275 /* build a header so we can delete the message later */
276 buf->magic = CR_FILE_BUFFER_MAGIC;
277 buf->kind = CRFileMemory;
278 buf->len = len;
279 buf->pad = 0;
280
281 crNetDispatchMessage( cr_file.recv_list, conn, msg, len );
282}
283
284static void
285crFileInstantReclaim( CRConnection *conn, CRMessage *mess )
286{
287 crFileFree( conn, mess );
288}
289
290void
291crFileInit( CRNetReceiveFuncList *rfl, CRNetCloseFuncList *cfl, unsigned int mtu )
292{
293 (void) mtu;
294
295 cr_file.recv_list = rfl;
296 cr_file.close_list = cfl;
297
298 if (cr_file.initialized)
299 {
300 return;
301 }
302
303 cr_file.num_conns = 0;
304 cr_file.conns = NULL;
305
306#ifdef CHROMIUM_THREADSAFE
307 crInitMutex(&cr_file.mutex);
308#endif
309 cr_file.bufpool = crBufferPoolInit(16);
310
311
312 cr_file.initialized = 1;
313}
314
315static int
316crFileDoConnect( CRConnection *conn )
317{
318 conn->file_direction = CR_FILE_WRITE;
319 /* NOTE: the third parameter (file permissions) is only used/required when
320 * we specify O_CREAT as part of the flags. The permissions will be
321 * masked according to the effective user's umask setting.
322 */
323#ifdef WINDOWS
324 conn->fd = open( conn->filename, O_CREAT | O_WRONLY | O_BINARY |
325 S_IREAD | S_IWRITE);
326#else
327 conn->fd = open( conn->filename, O_CREAT | O_WRONLY | O_BINARY,
328 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
329#endif
330 if (conn->fd < 0)
331 {
332 crWarning( "Couldn't open %s for writing!", conn->filename );
333 return 0;
334 }
335 return 1;
336}
337
338static void
339crFileDoDisconnect( CRConnection *conn )
340{
341 close( conn->fd );
342 conn->type = CR_NO_CONNECTION;
343 crMemcpy( cr_file.conns + conn->index, cr_file.conns + conn->index+1,
344 (cr_file.num_conns - conn->index - 1)*sizeof(*(cr_file.conns)) );
345 cr_file.num_conns--;
346}
347
348void
349crFileConnection( CRConnection *conn )
350{
351 int n_bytes;
352
353 CRASSERT( cr_file.initialized );
354
355 conn->type = CR_FILE;
356 conn->Alloc = crFileAlloc;
357 conn->Send = crFileSend;
358 conn->SendExact = crFileWriteExact;
359 conn->Recv = crFileSingleRecv;
360 conn->Free = crFileFree;
361 conn->Accept = crFileAccept;
362 conn->Connect = crFileDoConnect;
363 conn->Disconnect = crFileDoDisconnect;
364 conn->InstantReclaim = crFileInstantReclaim;
365 conn->HandleNewMessage = crFileHandleNewMessage;
366 conn->index = cr_file.num_conns;
367 conn->sizeof_buffer_header = sizeof( CRFileBuffer );
368 conn->actual_network = 0;
369
370 conn->filename = crStrdup( conn->hostname );
371
372 n_bytes = ( cr_file.num_conns + 1 ) * sizeof(*cr_file.conns);
373 crRealloc( (void **) &cr_file.conns, n_bytes );
374
375 cr_file.conns[cr_file.num_conns++] = conn;
376}
377
378CRConnection**
379crFileDump( int* num )
380{
381 *num = cr_file.num_conns;
382
383 return cr_file.conns;
384}
385
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use