vrpn  07.33
Virtual Reality Peripheral Network
vrpn_Imager_Stream_Buffer.h
Go to the documentation of this file.
1 #ifndef VRPN_IMAGER_STREAM_BUFFER_H
2 #define VRPN_IMAGER_STREAM_BUFFER_H
3 #include <string.h> // for NULL, strcpy, strlen
4 
6 #include "vrpn_Configure.h" // for VRPN_CALLBACK, VRPN_API
7 #include "vrpn_Connection.h" // for vrpn_Connection (ptr only), etc
8 #include "vrpn_Imager.h"
9 #include "vrpn_Shared.h" // for vrpn_Semaphore, etc
10 #include "vrpn_Types.h" // for vrpn_int32, vrpn_uint16
11 
12 // This is a fairly complicated class that implements a multi-threaded
13 // full-rate logger and partial-rate forwarder for a vrpn_Imager_Server
14 // object. It is intended to allow previewing of microscopy experiments
15 // at a subset of the camera's video rate while logging the video at
16 // full rate, possibly on a remote computer and possibly on the original
17 // video server computer. Its architecture is described in the "Full-rate
18 // logging" section of the vrpn_Imager.html document in the VRPN web
19 // page.
20 
21 //-------------------------------------------------------------------
22 // This is a helper class for the vrpn_Imager_Stream_Shared_State class
23 // below. It keeps a linked list of vrpn_HANDLERPARAM types and the
24 // buffers to which they point. The buffers need to be allocated by
25 // the one who inserts to this list and deleted by the one who pulls
26 // elements from this list.
27 
29 public:
31  {
32  d_first = d_last = NULL;
33  d_count = 0;
34  };
36  {
37  while (d_first != NULL) {
38  struct d_ELEMENT *next = d_first->next;
39  delete d_first;
40  d_first = next;
41  }
42  }
43 
44  // Give the length of the list.
45  unsigned size(void) const { return d_count; }
46 
47  // Insert an element into the list. Return false if fails.
49  {
50  struct d_ELEMENT *el = new struct d_ELEMENT;
51  if (el == NULL) {
52  return false;
53  }
54  el->p = p;
55  el->next = NULL;
56  if (d_last != NULL) {
57  d_last->next = el;
58  }
59  d_last = el;
60  if (d_first == NULL) {
61  d_first = el;
62  }
63  d_count++;
64  return true;
65  }
66 
67  // Remove an element from the list. Return false if fails.
69  {
70  if (p == NULL) {
71  return false;
72  }
73  if (size() == 0) {
74  return false;
75  }
76 
77  *p = d_first->p;
78  if (d_last == d_first) {
79  d_last = NULL;
80  }
81  struct d_ELEMENT *temp = d_first;
82  d_first = d_first->next;
83  delete temp;
84 
85  d_count--;
86  return true;
87  }
88 
89 protected:
90  struct d_ELEMENT {
92  struct d_ELEMENT *next;
93  };
94  struct d_ELEMENT *d_first, *d_last;
95  unsigned d_count;
96 };
97 
98 //-------------------------------------------------------------------
99 // This is the data structure that is shared between the initial
100 // thread (which listens for client connections) and the non-blocking logging
101 // thread that sometimes exists to listen to the vrpn_Imager_Server.
102 // All of its methods must be thread-safe, so it creates a semaphore
103 // for access and uses it in all of the non-atomic methods.
104 // Note that some of the things in here are pointers to objects that
105 // are in the parent class, and they are here just to provide the
106 // semaphore protection. The parent class should only access these
107 // things through this shared state object.
108 
110 public:
112 
113  // Reset the shared state to what it should be at
114  // the time the logging thread is started.
115  void init(void)
116  {
117  d_time_to_exit = false;
118  d_description_updated = false;
119  d_nRows = d_nCols = d_nDepth = d_nChannels = 0;
120  d_new_log_request = false;
121  d_request_lil = NULL;
122  d_request_lol = NULL;
123  d_request_ril = NULL;
124  d_request_rol = NULL;
125  d_new_log_result = false;
126  d_result_lil = NULL;
127  d_result_lol = NULL;
128  d_result_ril = NULL;
129  d_result_rol = NULL;
130  d_new_throttle_request = false;
131  d_throttle_count = -1;
132  d_frames_in_queue = 0;
133  }
134 
135  // Accessors for the "time to exit" flag; set by the initial thread and
136  // read by the logging thread.
137  bool time_to_exit(void)
138  {
139  d_sem.p();
140  bool ret = d_time_to_exit;
141  d_sem.v();
142  return ret;
143  }
144  void time_to_exit(bool do_exit)
145  {
146  d_sem.p();
147  d_time_to_exit = do_exit;
148  d_sem.v();
149  }
150 
151  // Accessors for the parameters stored based on the
152  // imager server's reports. Returns false if nothing has
153  // been set since the last time it was read, true (and fills in
154  // the values) if it has. Channel buffer must be delete [] by
155  // the one calling this function iff the function returns true.
156  bool get_imager_description(vrpn_int32 &nRows, vrpn_int32 &nCols,
157  vrpn_int32 &nDepth, vrpn_int32 &nChannels,
158  const char **channelBuffer)
159  {
160  d_sem.p();
161  bool ret = d_description_updated;
162  if (d_description_updated) {
163  nRows = d_nRows;
164  nCols = d_nCols;
165  nDepth = d_nDepth;
166  nChannels = d_nChannels;
167  *channelBuffer = d_channel_buffer;
168  }
169  d_description_updated = false;
170  d_sem.v();
171  return ret;
172  }
173  bool set_imager_description(vrpn_int32 nRows, vrpn_int32 nCols,
174  vrpn_int32 nDepth, vrpn_int32 nChannels,
175  const char *channelBuffer)
176  {
177  d_sem.p();
178  d_nRows = nRows;
179  d_nCols = nCols;
180  d_nDepth = nDepth;
181  d_nChannels = nChannels;
182  d_channel_buffer = channelBuffer;
183  d_description_updated = true;
184  d_sem.v();
185  return true;
186  }
187 
188  // Accessors for the initial thread to pass new logfile names down to the
189  // logging thread, which will cause it to initiate a changeover of logging
190  // connections. Space for the return strings will be allocated in these
191  // functions
192  // and must be deleted by the logging thread ONLY IF the get function fills
193  // the
194  // values in (it returns true if it does).
195  // NOTE: this is used to query BOTH the presence of new logfile names
196  // AS WELL AS the names themselves. this function will only return values
197  // if new logfile names have been requested since the last time this
198  // function was called.
199  bool get_logfile_request(char **lil, char **lol, char **ril, char **rol)
200  {
201  d_sem.p();
202  bool ret = d_new_log_request;
203  if (d_new_log_request) {
204  // Allocate space to return the names in the handles passed in.
205  // Copy the values from our local storage to the return values.
206  if ((*lil = new char[strlen(d_request_lil) + 1]) != NULL) {
207  strcpy(*lil, d_request_lil);
208  }
209  if ((*lol = new char[strlen(d_request_lol) + 1]) != NULL) {
210  strcpy(*lol, d_request_lol);
211  }
212  if ((*ril = new char[strlen(d_request_ril) + 1]) != NULL) {
213  strcpy(*ril, d_request_ril);
214  }
215  if ((*rol = new char[strlen(d_request_rol) + 1]) != NULL) {
216  strcpy(*rol, d_request_rol);
217  }
218 
219  // Delete and NULL the local storage pointers.
220  delete[] d_request_lil;
221  d_request_lil = NULL;
222  delete[] d_request_lol;
223  d_request_lol = NULL;
224  delete[] d_request_ril;
225  d_request_ril = NULL;
226  delete[] d_request_rol;
227  d_request_rol = NULL;
228  }
229  d_new_log_request = false;
230  d_sem.v();
231  return ret;
232  }
233 
234  void set_logfile_request(const char *lil, const char *lol, const char *ril,
235  const char *rol)
236  {
237  d_sem.p();
238 
239  // delete file names, in case the logging thread hasn't had a chance to
240  // honor the request yet.
241  if (d_request_lil) {
242  delete[] d_request_lil;
243  d_request_lil = NULL;
244  }
245  if (d_request_lol) {
246  delete[] d_request_lol;
247  d_request_lol = NULL;
248  }
249  if (d_request_ril) {
250  delete[] d_request_ril;
251  d_request_ril = NULL;
252  }
253  if (d_request_rol) {
254  delete[] d_request_rol;
255  d_request_rol = NULL;
256  }
257 
258  // Allocate space for each string and then copy into it.
259  if (lil != NULL) {
260  if ((d_request_lil = new char[strlen(lil) + 1]) != NULL) {
261  strcpy(d_request_lil, lil);
262  }
263  }
264  if (lol != NULL) {
265  if ((d_request_lol = new char[strlen(lol) + 1]) != NULL) {
266  strcpy(d_request_lol, lol);
267  }
268  }
269  if (ril != NULL) {
270  if ((d_request_ril = new char[strlen(ril) + 1]) != NULL) {
271  strcpy(d_request_ril, ril);
272  }
273  }
274  if (rol != NULL) {
275  if ((d_request_rol = new char[strlen(rol) + 1]) != NULL) {
276  strcpy(d_request_rol, rol);
277  }
278  }
279 
280  d_new_log_request = true;
281  d_sem.v();
282  }
283 
284  // Accessors for the logfile thread to pass new logfile names back up to the
285  // initial thread, reporting a changeover of logging connections.
286  // Space for the return strings will be allocated in these functions
287  // and must be deleted by the initial thread ONLY IF the get function fills
288  // the
289  // values in (it returns true if it does).
290  // NOTE: this function is intended to query BOTH the logfile names AS WELL
291  // AS
292  // the change in logging status. it ONLY returns filenames if logging has
293  // changed since the last time this function was called).
294  bool get_logfile_result(char **lil, char **lol, char **ril, char **rol)
295  {
296  d_sem.p();
297  bool ret = d_new_log_result;
298  if (d_new_log_result) {
299  // Allocate space to return the names in the handles passed in.
300  // Copy the values from our local storage to the return values.
301  if (d_result_lil == NULL)
302  *lil = NULL;
303  else {
304  if ((*lil = new char[strlen(d_result_lil) + 1]) != NULL) {
305  strcpy(*lil, d_result_lil);
306  }
307  }
308  if (d_result_lol == NULL)
309  *lol = NULL;
310  else {
311  if ((*lol = new char[strlen(d_result_lol) + 1]) != NULL) {
312  strcpy(*lol, d_result_lol);
313  }
314  }
315  if (d_result_ril == NULL)
316  *ril = NULL;
317  else {
318  if ((*ril = new char[strlen(d_result_ril) + 1]) != NULL) {
319  strcpy(*ril, d_result_ril);
320  }
321  }
322  if (d_result_rol == NULL)
323  *rol = NULL;
324  else {
325  if ((*rol = new char[strlen(d_result_rol) + 1]) != NULL) {
326  strcpy(*rol, d_result_rol);
327  }
328  }
329 
330  // do not Delete and NULL the local storage pointers.
331  // someone may request the filenames later.
332  }
333  d_new_log_result = false;
334  d_sem.v();
335  return ret;
336  }
337 
338  void set_logfile_result(const char *lil, const char *lol, const char *ril,
339  const char *rol)
340  {
341  d_sem.p();
342 
343  if (d_result_lil) delete[] d_result_lil;
344  d_result_lil = NULL;
345  if (d_result_lol) delete[] d_result_lol;
346  d_result_lol = NULL;
347  if (d_result_ril) delete[] d_result_ril;
348  d_result_ril = NULL;
349  if (d_result_rol) delete[] d_result_rol;
350  d_result_rol = NULL;
351 
352  // Allocate space for each string and then copy into it.
353  if (lil != NULL) {
354  if ((d_result_lil = new char[strlen(lil) + 1]) != NULL) {
355  strcpy(d_result_lil, lil);
356  }
357  }
358  if (lol != NULL) {
359  if ((d_result_lol = new char[strlen(lol) + 1]) != NULL) {
360  strcpy(d_result_lol, lol);
361  }
362  }
363  if (ril != NULL) {
364  if ((d_result_ril = new char[strlen(ril) + 1]) != NULL) {
365  strcpy(d_result_ril, ril);
366  }
367  }
368  if (rol != NULL) {
369  if ((d_result_rol = new char[strlen(rol) + 1]) != NULL) {
370  strcpy(d_result_rol, rol);
371  }
372  }
373 
374  d_new_log_result = true;
375  d_sem.v();
376  }
377 
378  // fills in the arguments with the logfile names currently in use
379  // for a particular log, the value will be NULL if that log is not being
380  // collected.
381  // NOTE: this function allocates memory for each string returned. IT IS
382  // THE
383  // RESPONSIBILITY OF THE CALLING FUNCTION TO FREE THIS MEMORY.
384  void get_logfile_names(char **local_in, char **local_out, char **remote_in,
385  char **remote_out)
386  {
387  d_sem.p();
388  if (d_result_lil == NULL)
389  *local_in = NULL;
390  else {
391  *local_in = new char[strlen(d_result_lil) + 1];
392  strcpy(*local_in, d_result_lil);
393  }
394  if (d_result_lol == NULL)
395  *local_out = NULL;
396  else {
397  *local_out = new char[strlen(d_result_lol) + 1];
398  strcpy(*local_out, d_result_lol);
399  }
400  if (d_result_ril == NULL)
401  *remote_in = NULL;
402  else {
403  *remote_in = new char[strlen(d_result_ril) + 1];
404  strcpy(*remote_in, d_result_ril);
405  }
406  if (d_result_rol == NULL)
407  *remote_out = NULL;
408  else {
409  *remote_out = new char[strlen(d_result_rol) + 1];
410  strcpy(*remote_out, d_result_rol);
411  }
412  d_sem.v();
413  }
414 
415  // Accessors for the initial thread to pass new throttle values down to the
416  // logging thread, which will cause it to throttle as needed.
417  bool get_throttle_request(vrpn_int32 *throttle_count)
418  {
419  d_sem.p();
420  bool ret = d_new_throttle_request;
421  if (d_new_throttle_request) {
422  *throttle_count = d_throttle_count;
423  }
424  d_new_throttle_request = false;
425  d_sem.v();
426  return ret;
427  }
428  void set_throttle_request(vrpn_int32 throttle_count)
429  {
430  d_sem.p();
431  d_throttle_count = throttle_count;
432  d_new_throttle_request = true;
433  d_sem.v();
434  }
435 
436  // Accessors for the logging thread to increment and read the number of
437  // frames in the queue and for the initial thread to decrement them. The
438  // increment/decrement is done when a begin_frame message is found. The
439  // increment/decrement routines return the new value.
440  vrpn_int32 get_frames_in_queue(void)
441  {
442  d_sem.p();
443  vrpn_int32 ret = d_frames_in_queue;
444  d_sem.v();
445  return ret;
446  }
447  vrpn_int32 increment_frames_in_queue(void)
448  {
449  d_sem.p();
450  d_frames_in_queue++;
451  vrpn_int32 ret = d_frames_in_queue;
452  d_sem.v();
453  return ret;
454  }
455  vrpn_int32 decrement_frames_in_queue(void)
456  {
457  d_sem.p();
458  d_frames_in_queue--;
459  vrpn_int32 ret = d_frames_in_queue;
460  d_sem.v();
461  return ret;
462  }
463 
464  // Accessors for the logging thread to add messages to the queue
465  // and for the initial thread to retrieve and count them.
467  {
468  d_sem.p();
469  vrpn_int32 ret = d_logger_to_client_messages.size();
470  d_sem.v();
471  return ret;
472  }
474  {
475  d_sem.p();
476  bool ret = d_logger_to_client_messages.insert_back(p);
477  d_sem.v();
478  return ret;
479  }
481  {
482  d_sem.p();
483  bool ret = d_logger_to_client_messages.retrieve_front(p);
484  d_sem.v();
485  return ret;
486  }
487 
488 protected:
489  vrpn_Semaphore d_sem; // Semaphore to control access to data items.
490 
491  // Is it time for the logging thread to exit?
493 
494  // Stored copies of the value in the vrpn_Imager_Remote and a flag telling
495  // whether they have changed since last read.
496  bool d_description_updated; // Do we have a new description from imager
497  // server?
498  vrpn_int32 d_nRows;
499  vrpn_int32 d_nCols;
500  vrpn_int32 d_nDepth;
501  vrpn_int32 d_nChannels;
502  const char *d_channel_buffer; //< Allocated by sender, freed by receiver
503 
504  // Names of the log files passed from the initial thread to the logging
505  // thread and a flag telling whether they have been changed since last
506  // read.
512 
513  // Names of the log files passed from the logging thread to the initial
514  // thread and a flag telling whether they have been changed since last
515  // read. NOTE: we maintain a copy of the log file names here, instead
516  // of using the accessor of vrpn_Connection to query the names. Only
517  // the logging thread is supposed to have access to the logging connection,
518  // but the logging thread is banned from calling methods on the client
519  // connection.
525 
526  // New throttle request passed on by the client-handling thread
528  vrpn_int32 d_throttle_count;
529 
530  // Records the number of frames in the queue. This is incremented
531  // by the non-blocking thread and decremented by the initial thread
532  // as the begin_frame() messages are queued and dequeued.
533  vrpn_int32 d_frames_in_queue;
534 
535  // List of messages passing from the logging thread to the initial
536  // thread.
538 };
539 
540 //-------------------------------------------------------------------
541 // This class is a vrpn_Imager_Server; it has one or two instances of
542 // vrpn_Imager_Clients to talk to the server it is forwarding packets
543 // to. It does not use their callback parsers, but rather hooks its own
544 // callbacks directly to the connection object for the server it is
545 // buffering.
546 
548  public vrpn_Imager_Server {
549 public:
550  // Name of this object (the server side of the vrpn_Imager that is
551  // buffered and the vrpn_Auxiliary_Logger that the client will connect to).
552  // (Optional, can be NULL) pointer to the server connection on which to
553  // communicate.
554  // Name of the vrpn_Imager_Server to connect to (packets from this server
555  // will
556  // be forwarded to the main connection, and logging will occur on the
557  // connection
558  // to this imager_server). This server may be local or remote; if local,
559  // include "@localhost" in the name because new connections will be made to
560  // it.
561  vrpn_Imager_Stream_Buffer(const char *name, const char *imager_server_name,
562  vrpn_Connection *c);
563 
564  // Get rid of any logging thread and then clean up.
565  virtual ~vrpn_Imager_Stream_Buffer();
566 
567  // Required for servers.
568  virtual void mainloop(void);
569 
570 protected:
571  // Handle a logging-request message. The request contains four file
572  // names, two for local (to the Auxiliary server itself) and two for
573  // remote (the far side of its connection to the server). It must
574  // also respond to the client with a message saying what logging has
575  // been set up (using the send_logging_response function). Logging is
576  // turned off on a particular file by sending an empty-string name ("").
577  // The in/out local/remote are with respect to the connection that the
578  // logging is to occur on, which is to the imager server whose name is
579  // passed in to the constructor, not the connection that the client has
580  // sent the request on.
581  // Make sure to send a response saying what you did.
582  virtual void handle_request_logging(const char *local_in_logfile_name,
583  const char *local_out_logfile_name,
584  const char *remote_in_logfile_name,
585  const char *remote_out_logfile_name);
586 
587  // Static portion of handling (unpacking) the request_logging message. It
588  // then calls the non-static virtual method above.
589  static int VRPN_CALLBACK
591 
592  virtual void handle_request_logging_status();
593 
594  // Handle dropped last connection on our primary connection by shutting down
595  // the
596  // connection to the imager server. The static method in the base class
597  // looks up this
598  // pointer and calls the virtual method.
599  virtual void handle_dropped_last_connection(void);
600 
601  // Handles a throttle request by passing it on down to the non-blocking
602  // thread to deal with.
603  static int VRPN_CALLBACK
604  static_handle_throttle_message(void *userdata, vrpn_HANDLERPARAM p);
605 
606  // Handle got first connection request by (having the second thread) create
607  // a connection to the server and waiting until we get a description message
608  // from the imager server we're listening to. Timeout after a while if the
609  // connection cannot be made or the server does not respond.
610  virtual void handle_got_first_connection(void);
611  vrpn_int32 got_first_connection_m_id; // ID of message that we got the first
612  // connection
613  static int VRPN_CALLBACK
614  static_handle_got_first_connection(void *userdata, vrpn_HANDLERPARAM p);
615 
616  // State shared between the initial thread and the logging thread.
618 
619  //----------------------------------------------------------------------
620  // The section below includes methods and member variables that should
621  // only be used by the logging thread. They are not protected by
622  // semaphores and so should not be accessed except within the
623  // logging_thread_func().
624 
625  // This class spawns a new thread to handle uninterrupted communication
626  // and logging with the vrpn_Imager_Server that we are forwarding messages
627  // for. This is created in the constructor and shut down (hopefully gently)
628  // in the destructor. There are a number of semaphores that are used by
629  // the initial thread and the logging thread to communicate.
631 
632  // The function that is called to become the logging thread. It is passed
633  // a pointer to "this" so that it can acces the object that created it.
634  // Note that it must use semaphores to get at the data that will be shared
635  // between the main thread and itself. The static function basically just
636  // pulls the "this" pointer out and then calls the non-static function.
637  static void static_logging_thread_func(vrpn_ThreadData &threadData);
638  void logging_thread_func(void);
639 
640  // Stop the logging thread function, cleanly if possible. Returns true if
641  // the function stopped cleanly, false if it had to be killed.
642  bool stop_logging_thread(void);
643 
644  // Name of the vrpn_Imager_Server object we are to connect to and
645  // log/pass messages from.
647 
648  // Are we ready to drop the old connection (new one has received its
649  // descriptor message)?
651 
652  // The connection that is used to talk to the client.
655  open_new_log_connection(const char *local_in_logfile_name,
656  const char *local_out_logfile_name,
657  const char *remote_in_logfile_name,
658  const char *remote_out_logfile_name);
659 
660  // These will create/destroy the d_imager_remote and other callback handlers
661  // needed to provide the handling of messages from the logging connection
662  // passed in; they are used by the initial-connection code and by the
663  // code that handles handing off from an old connection to a new connection
664  // when a new logging message is received.
665  bool setup_handlers_for_logging_connection(vrpn_Connection *c);
666  bool teardown_handlers_for_logging_connection(vrpn_Connection *c);
667 
668  // This is yet another "create me some logs" function; it handles the
669  // hand-off from one log file to another within the logging thread.
670  // It is called by the main logging thread function when a request comes in
671  // from the initial thread to perform logging.
672  bool make_new_logging_connection(const char *local_in_logfile_name,
673  const char *local_out_logfile_name,
674  const char *remote_in_logfile_name,
675  const char *remote_out_logfile_name);
676 
677  // The imager remote to listen to the vrpn_Imager_Server, along
678  // with the callback functions that support its operation. The
679  // generic VRPN callback handler that receives all messages from
680  // the imager server and either queues them or handles them, there
681  // is a static version that just gets a this pointer and calls the
682  // non-static function.
684  static void VRPN_CALLBACK
685  handle_image_description(void *pvISB, const struct timeval msg_time);
686  static int VRPN_CALLBACK
687  static_handle_server_messages(void *pvISB, vrpn_HANDLERPARAM p);
688  int handle_server_messages(const vrpn_HANDLERPARAM &p);
689 
690  // Types of messages we expect to be coming from the server.
691  vrpn_int32 d_server_description_m_id; //< ID of the message type describing
692  // the range and channels
693  vrpn_int32 d_server_begin_frame_m_id; //< ID of the message type describing
694  // the start of a region
695  vrpn_int32 d_server_end_frame_m_id; //< ID of the message type describing
696  // the start of a region
697  vrpn_int32 d_server_discarded_frames_m_id; //< ID of the message type
698  // describing the discarding of
699  // one or more regions
700  vrpn_int32 d_server_regionu8_m_id; //< ID of the message type describing a
701  // region with 8-bit unsigned entries
702  vrpn_int32 d_server_regionu12in16_m_id; //< ID of the message type
703  // describing a region with 12-bit
704  // unsigned entries packed in 16 bits
705  vrpn_int32 d_server_regionu16_m_id; //< ID of the message type describing a
706  // region with 16-bit unsigned entries
707  vrpn_int32 d_server_regionf32_m_id; //< ID of the message type describing a
708  // region with 32-bit float entries
709  vrpn_int32 d_server_text_m_id; //< ID of the system text message
710  vrpn_int32 d_server_ping_m_id; //< ID of the system ping message
711  vrpn_int32 d_server_pong_m_id; //< ID of the system pong message
712 
713  // Transcode the sender and type fields from the logging server connection
714  // to
715  // the initial client connection and pack the resulting message into the
716  // queue
717  // from the logging thread to the initial thread. The data buffer is
718  // copied;
719  // this space is allocated by the logging thread and must be freed by the
720  // initial thread.
721  // Returns true on success and false on failure. The sender is set to the
722  // d_sender_id of our server object.
723  bool transcode_and_send(const vrpn_HANDLERPARAM &p);
724 
725  // Transcode the type from the logging thread's connection type to
726  // the initial thread's connection type. Return -1 if we don't
727  // recognize the type.
728  vrpn_int32 transcode_type(vrpn_int32 type);
729 
730  // Handling throttling on the non-blocking thread. This is a shadow
731  // copy of the structures in the vrpn_Image_Server base class; we cannot
732  // use those directly because they will be adjusted by their own callbacks
733  // in the initial thread.
736 };
737 
738 //-----------------------------------------------------------
739 // Client code should connect to the server twice, once as
740 // a vrpn_Imager_Server and once as a vrpn_Auxiliary_Logger_Server.
741 // There is not a special remote class for this.
742 
743 #endif
vrpn_Imager_Stream_Shared_State::get_frames_in_queue
vrpn_int32 get_frames_in_queue(void)
Definition: vrpn_Imager_Stream_Buffer.h:440
vrpn_Imager_Stream_Buffer::d_server_text_m_id
vrpn_int32 d_server_text_m_id
Definition: vrpn_Imager_Stream_Buffer.h:709
vrpn_Imager_Stream_Shared_State::d_throttle_count
vrpn_int32 d_throttle_count
Definition: vrpn_Imager_Stream_Buffer.h:528
vrpn_Imager_Stream_Shared_State::d_result_ril
char * d_result_ril
Definition: vrpn_Imager_Stream_Buffer.h:523
vrpn_Types.h
vrpn_Semaphore
Definition: vrpn_Shared.h:487
vrpn_Imager_Stream_Shared_State::init
void init(void)
Definition: vrpn_Imager_Stream_Buffer.h:115
vrpn_Auxiliary_Logger_Server::handle_request_logging_status
virtual void handle_request_logging_status()=0
vrpn_Thread
Definition: vrpn_Shared.h:558
vrpn_Imager_Stream_Buffer::d_log_connection
vrpn_Connection * d_log_connection
Definition: vrpn_Imager_Stream_Buffer.h:653
vrpn_Imager_Stream_Shared_State::d_request_lil
char * d_request_lil
Definition: vrpn_Imager_Stream_Buffer.h:508
vrpn_Imager_Stream_Buffer::d_server_discarded_frames_m_id
vrpn_int32 d_server_discarded_frames_m_id
Definition: vrpn_Imager_Stream_Buffer.h:697
vrpn_Message_List::~vrpn_Message_List
~vrpn_Message_List(void)
Definition: vrpn_Imager_Stream_Buffer.h:35
vrpn_Imager_Stream_Buffer::d_server_ping_m_id
vrpn_int32 d_server_ping_m_id
Definition: vrpn_Imager_Stream_Buffer.h:710
vrpn_Auxiliary_Logger_Server::handle_request_logging
virtual void handle_request_logging(const char *local_in_logfile_name, const char *local_out_logfile_name, const char *remote_in_logfile_name, const char *remote_out_logfile_name)=0
vrpn_Imager_Stream_Buffer::d_ready_to_drop_old_connection
bool d_ready_to_drop_old_connection
Definition: vrpn_Imager_Stream_Buffer.h:650
vrpn_Imager_Stream_Shared_State::get_logfile_result
bool get_logfile_result(char **lil, char **lol, char **ril, char **rol)
Definition: vrpn_Imager_Stream_Buffer.h:294
vrpn_Imager_Stream_Shared_State::d_frames_in_queue
vrpn_int32 d_frames_in_queue
Definition: vrpn_Imager_Stream_Buffer.h:533
vrpn_Imager_Stream_Shared_State::set_logfile_result
void set_logfile_result(const char *lil, const char *lol, const char *ril, const char *rol)
Definition: vrpn_Imager_Stream_Buffer.h:338
vrpn_Message_List::d_count
unsigned d_count
Definition: vrpn_Imager_Stream_Buffer.h:95
vrpn_Auxiliary_Logger_Server::handle_dropped_last_connection
virtual void handle_dropped_last_connection(void)
Definition: vrpn_Auxiliary_Logger.C:268
vrpn_Imager_Stream_Buffer::d_server_regionf32_m_id
vrpn_int32 d_server_regionf32_m_id
Definition: vrpn_Imager_Stream_Buffer.h:707
vrpn_Message_List::d_last
struct d_ELEMENT * d_last
Definition: vrpn_Imager_Stream_Buffer.h:94
vrpn_Imager_Stream_Buffer::d_server_dropped_due_to_throttle
vrpn_uint16 d_server_dropped_due_to_throttle
Definition: vrpn_Imager_Stream_Buffer.h:734
vrpn_Message_List::vrpn_Message_List
vrpn_Message_List(void)
Definition: vrpn_Imager_Stream_Buffer.h:30
vrpn_Imager_Stream_Shared_State::d_nCols
vrpn_int32 d_nCols
Definition: vrpn_Imager_Stream_Buffer.h:499
vrpn_Imager_Stream_Buffer::d_server_regionu16_m_id
vrpn_int32 d_server_regionu16_m_id
Definition: vrpn_Imager_Stream_Buffer.h:705
vrpn_Auxiliary_Logger_Server::static_handle_request_logging
static int VRPN_CALLBACK static_handle_request_logging(void *userdata, vrpn_HANDLERPARAM p)
Definition: vrpn_Auxiliary_Logger.C:298
vrpn_Imager_Stream_Buffer::got_first_connection_m_id
vrpn_int32 got_first_connection_m_id
Definition: vrpn_Imager_Stream_Buffer.h:611
vrpn_Imager_Stream_Shared_State::get_logger_to_client_queue_size
vrpn_int32 get_logger_to_client_queue_size(void)
Definition: vrpn_Imager_Stream_Buffer.h:466
vrpn_Imager_Stream_Shared_State::d_result_lol
char * d_result_lol
Definition: vrpn_Imager_Stream_Buffer.h:522
vrpn_Imager_Stream_Buffer::d_server_begin_frame_m_id
vrpn_int32 d_server_begin_frame_m_id
Definition: vrpn_Imager_Stream_Buffer.h:693
vrpn_Auxiliary_Logger_Server::mainloop
virtual void mainloop(void)
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition: vrpn_Auxiliary_Logger.h:70
vrpn_Imager_Stream_Shared_State::time_to_exit
void time_to_exit(bool do_exit)
Definition: vrpn_Imager_Stream_Buffer.h:144
vrpn_Imager_Stream_Shared_State::decrement_frames_in_queue
vrpn_int32 decrement_frames_in_queue(void)
Definition: vrpn_Imager_Stream_Buffer.h:455
vrpn_Message_List::retrieve_front
bool retrieve_front(vrpn_HANDLERPARAM *p)
Definition: vrpn_Imager_Stream_Buffer.h:68
vrpn_Imager_Stream_Shared_State::d_sem
vrpn_Semaphore d_sem
Definition: vrpn_Imager_Stream_Buffer.h:489
vrpn_Imager_Stream_Buffer::d_server_regionu12in16_m_id
vrpn_int32 d_server_regionu12in16_m_id
Definition: vrpn_Imager_Stream_Buffer.h:702
vrpn_ThreadData
Definition: vrpn_Shared.h:548
vrpn_HANDLERPARAM
This structure is what is passed to a vrpn_Connection message callback.
Definition: vrpn_Connection.h:44
vrpn_Shared.h
vrpn_Imager_Stream_Shared_State::set_logfile_request
void set_logfile_request(const char *lil, const char *lol, const char *ril, const char *rol)
Definition: vrpn_Imager_Stream_Buffer.h:234
vrpn_Imager_Stream_Shared_State::get_logfile_request
bool get_logfile_request(char **lil, char **lol, char **ril, char **rol)
Definition: vrpn_Imager_Stream_Buffer.h:199
vrpn_Imager_Stream_Shared_State::retrieve_logger_to_client_message
bool retrieve_logger_to_client_message(vrpn_HANDLERPARAM *p)
Definition: vrpn_Imager_Stream_Buffer.h:480
vrpn_Imager_Stream_Shared_State::get_imager_description
bool get_imager_description(vrpn_int32 &nRows, vrpn_int32 &nCols, vrpn_int32 &nDepth, vrpn_int32 &nChannels, const char **channelBuffer)
Definition: vrpn_Imager_Stream_Buffer.h:156
vrpn_Imager_Stream_Buffer::d_server_pong_m_id
vrpn_int32 d_server_pong_m_id
Definition: vrpn_Imager_Stream_Buffer.h:711
vrpn_Imager_Stream_Shared_State::time_to_exit
bool time_to_exit(void)
Definition: vrpn_Imager_Stream_Buffer.h:137
vrpn_Imager_Stream_Buffer::d_server_regionu8_m_id
vrpn_int32 d_server_regionu8_m_id
Definition: vrpn_Imager_Stream_Buffer.h:700
vrpn_Message_List::d_ELEMENT::next
struct d_ELEMENT * next
Definition: vrpn_Imager_Stream_Buffer.h:92
vrpn_Imager_Stream_Shared_State::d_description_updated
bool d_description_updated
Definition: vrpn_Imager_Stream_Buffer.h:496
vrpn_Imager_Stream_Buffer::d_server_end_frame_m_id
vrpn_int32 d_server_end_frame_m_id
Definition: vrpn_Imager_Stream_Buffer.h:695
vrpn_Connection
Generic connection class not specific to the transport mechanism.
Definition: vrpn_Connection.h:510
vrpn_Connection.h
vrpn_Imager_Stream_Shared_State::d_logger_to_client_messages
vrpn_Message_List d_logger_to_client_messages
Definition: vrpn_Imager_Stream_Buffer.h:537
vrpn_Imager_Stream_Buffer::d_imager_remote
vrpn_Imager_Remote * d_imager_remote
Definition: vrpn_Imager_Stream_Buffer.h:683
vrpn_Imager_Stream_Buffer::d_server_frames_to_send
vrpn_int32 d_server_frames_to_send
Definition: vrpn_Imager_Stream_Buffer.h:735
vrpn_Message_List::size
unsigned size(void) const
Definition: vrpn_Imager_Stream_Buffer.h:45
vrpn_Imager_Stream_Buffer::d_logging_thread
vrpn_Thread * d_logging_thread
Definition: vrpn_Imager_Stream_Buffer.h:630
vrpn_Imager_Stream_Buffer::d_shared_state
vrpn_Imager_Stream_Shared_State d_shared_state
Definition: vrpn_Imager_Stream_Buffer.h:617
vrpn_Imager_Stream_Shared_State::d_nDepth
vrpn_int32 d_nDepth
Definition: vrpn_Imager_Stream_Buffer.h:500
vrpn_Imager_Stream_Shared_State::d_new_log_result
bool d_new_log_result
Definition: vrpn_Imager_Stream_Buffer.h:520
vrpn_Imager_Stream_Shared_State::vrpn_Imager_Stream_Shared_State
vrpn_Imager_Stream_Shared_State()
Definition: vrpn_Imager_Stream_Buffer.h:111
vrpn_Message_List::insert_back
bool insert_back(const vrpn_HANDLERPARAM &p)
Definition: vrpn_Imager_Stream_Buffer.h:48
vrpn_Imager_Stream_Buffer
Definition: vrpn_Imager_Stream_Buffer.h:547
VRPN_CALLBACK
#define VRPN_CALLBACK
Definition: vrpn_Configure.h:647
vrpn_Imager_Stream_Buffer::d_server_description_m_id
vrpn_int32 d_server_description_m_id
Definition: vrpn_Imager_Stream_Buffer.h:691
vrpn_Imager_Stream_Shared_State::d_channel_buffer
const char * d_channel_buffer
Definition: vrpn_Imager_Stream_Buffer.h:502
vrpn_Imager_Stream_Shared_State::d_request_ril
char * d_request_ril
Definition: vrpn_Imager_Stream_Buffer.h:510
vrpn_Imager_Stream_Shared_State::d_nChannels
vrpn_int32 d_nChannels
Definition: vrpn_Imager_Stream_Buffer.h:501
vrpn_Imager_Stream_Shared_State::d_result_rol
char * d_result_rol
Definition: vrpn_Imager_Stream_Buffer.h:524
vrpn_Imager_Stream_Shared_State::d_request_rol
char * d_request_rol
Definition: vrpn_Imager_Stream_Buffer.h:511
vrpn_Imager_Stream_Shared_State::d_new_log_request
bool d_new_log_request
Definition: vrpn_Imager_Stream_Buffer.h:507
vrpn_Message_List::d_ELEMENT::p
vrpn_HANDLERPARAM p
Definition: vrpn_Imager_Stream_Buffer.h:91
vrpn_Imager_Stream_Shared_State::set_throttle_request
void set_throttle_request(vrpn_int32 throttle_count)
Definition: vrpn_Imager_Stream_Buffer.h:428
vrpn_Imager_Stream_Shared_State::get_logfile_names
void get_logfile_names(char **local_in, char **local_out, char **remote_in, char **remote_out)
Definition: vrpn_Imager_Stream_Buffer.h:384
vrpn_Imager_Stream_Shared_State::set_imager_description
bool set_imager_description(vrpn_int32 nRows, vrpn_int32 nCols, vrpn_int32 nDepth, vrpn_int32 nChannels, const char *channelBuffer)
Definition: vrpn_Imager_Stream_Buffer.h:173
vrpn_Configure.h
vrpn_Imager_Stream_Shared_State::d_result_lil
char * d_result_lil
Definition: vrpn_Imager_Stream_Buffer.h:521
vrpn_Imager_Stream_Shared_State::insert_logger_to_client_message
bool insert_logger_to_client_message(const vrpn_HANDLERPARAM &p)
Definition: vrpn_Imager_Stream_Buffer.h:473
vrpn_Message_List::d_ELEMENT
Definition: vrpn_Imager_Stream_Buffer.h:90
vrpn_Imager_Remote
This is the class users deal with: it tells the format and the region data when it arrives.
Definition: vrpn_Imager.h:623
vrpn_Imager_Server
Definition: vrpn_Imager.h:156
vrpn_Auxiliary_Logger_Server
Definition: vrpn_Auxiliary_Logger.h:65
vrpn_Imager_Stream_Shared_State
Definition: vrpn_Imager_Stream_Buffer.h:109
vrpn_Message_List
Definition: vrpn_Imager_Stream_Buffer.h:28
vrpn_Imager_Stream_Shared_State::get_throttle_request
bool get_throttle_request(vrpn_int32 *throttle_count)
Definition: vrpn_Imager_Stream_Buffer.h:417
VRPN_API
#define VRPN_API
Definition: vrpn_Configure.h:646
vrpn_Imager_Stream_Shared_State::increment_frames_in_queue
vrpn_int32 increment_frames_in_queue(void)
Definition: vrpn_Imager_Stream_Buffer.h:447
vrpn_Imager.h
vrpn_Imager_Stream_Shared_State::d_time_to_exit
bool d_time_to_exit
Definition: vrpn_Imager_Stream_Buffer.h:492
vrpn_Imager_Stream_Shared_State::d_request_lol
char * d_request_lol
Definition: vrpn_Imager_Stream_Buffer.h:509
vrpn_Imager_Stream_Shared_State::d_new_throttle_request
bool d_new_throttle_request
Definition: vrpn_Imager_Stream_Buffer.h:527
vrpn_Imager_Stream_Buffer::d_imager_server_name
char * d_imager_server_name
Definition: vrpn_Imager_Stream_Buffer.h:646
vrpn_Imager_Stream_Shared_State::d_nRows
vrpn_int32 d_nRows
Definition: vrpn_Imager_Stream_Buffer.h:498
vrpn_Auxiliary_Logger.h