vrpn  07.33
Virtual Reality Peripheral Network
vrpn_Imager_Stream_Buffer.C
Go to the documentation of this file.
1 #include <stdio.h> // for fprintf, NULL, stderr, etc
2 
3 #include "vrpn_BaseClass.h" // for ::vrpn_TEXT_ERROR, etc
5 
7  const char *name, const char *imager_server_name, vrpn_Connection *c)
10  name, c, 0, 0) // Default number of rows and columns for the device.
11  , d_logging_thread(NULL)
12  , d_imager_server_name(NULL)
13 {
14  // Copy the name of the server we are to connect to when we are logging.
15  d_imager_server_name = new char[strlen(imager_server_name) + 1];
16  if (d_imager_server_name == NULL) {
17  fprintf(stderr, "vrpn_Imager_Stream_Buffer::vrpn_Imager_Stream_Buffer: "
18  "Out of memory\n");
19  d_connection = NULL;
20  return;
21  }
22  strcpy(d_imager_server_name, imager_server_name);
23 
24  // Create the logging thread but do not run it yet.
25  vrpn_ThreadData td;
26  td.pvUD = this;
28  if (d_logging_thread == NULL) {
29  fprintf(stderr, "vrpn_Imager_Stream_Buffer::vrpn_Imager_Stream_Buffer: "
30  "can't create logging thread\n");
31  d_connection = NULL;
32  return;
33  }
34 
35  // Register a handler for the got first connection message.
38  if (got_first_connection_m_id == -1) {
39  fprintf(stderr, "vrpn_Imager_Stream_Buffer::vrpn_Imager_Stream_Buffer: "
40  "can't register got first connection type\n");
41  d_connection = NULL;
42  return;
43  }
46  vrpn_ANY_SENDER)) {
47  fprintf(stderr, "vrpn_Imager_Stream_Buffer::vrpn_Imager_Stream_Buffer: "
48  "can't register got first connection handler\n");
49  d_connection = NULL;
50  }
51 
52  // The base server class implements throttling for us, so we could just go
53  // ahead
54  // and try to send the messages all the time using the normal frame
55  // begin/end and
56  // region routines. If we do this, though, we're going to have to unpack
57  // and repack
58  // all of the messages. If we re-implement the throttling code, then we can
59  // just
60  // watch the packets as they go by and see what types they are, discarding
61  // as
62  // appropriate (but we still have to queue and watch them).
63  // If we implement the throttling
64  // code down in the thread that listens to the server, we can avoid putting
65  // them into the queue at all. In that case, there can be a frame or more
66  // in
67  // the queue that would drain even after the throttle message was received.
68  // We can subtract the number of frames in the buffer from the request if
69  // the
70  // request is large enough, thus removing the problem, but it won't work for
71  // the common case of requesting 0 or 1 frames. This will work in the
72  // steady
73  // state, where a sender requests one more each time it gets one, but there
74  // will be an initial bolus of images.
75  // Nonetheless, this seems like the cleanest solution. So, we will
76  // install
77  // a handler for the throttling message that will pass it on down to the
78  // thread
79  // that is baby-sitting the server object.
82  vrpn_ANY_SENDER)) {
83  fprintf(stderr, "vrpn_Imager_Stream_Buffer::vrpn_Imager_Stream_Buffer: "
84  "can't register throttle handler\n");
85  d_connection = NULL;
86  }
87 }
88 
90 {
93  delete[] d_imager_server_name;
94  d_imager_server_name = NULL;
95  }
96 }
97 
99 {
100  // Required from all servers
101  server_mainloop();
102 
103  // See if we have a new image description from a logging thread. If so,
104  // fill in our values and send a description to any attached clients.
105  const char *channelBuffer = NULL;
107  d_nChannels, &channelBuffer)) {
108  int i;
109  const char *bufptr = channelBuffer;
110  for (i = 0; i < d_nChannels; i++) {
111  d_channels[i].unbuffer(&bufptr);
112  }
113  delete[] const_cast<char *>(channelBuffer);
115  }
116 
117  // See if we have any messages waiting in the queue from the logging thread.
118  // If we do, get an initial count and then send that many messages to the
119  // client. Don't go looking again this iteration or we may never return --
120  // the server is quite possibly packing frames faster than we can send them.
121  // Note that the messages in the queue have already been transcoded for our
122  // and sender ID.
124  if (count) {
125  unsigned i;
126  for (i = 0; i < count; i++) {
127  // Read the next message from the queue.
130  fprintf(stderr, "vrpn_Imager_Stream_Buffer::mainloop(): Could "
131  "not retrieve message from queue\n");
132  break;
133  }
134 
135  // Decrement the in-buffer frame count whenever we see a begin_frame
136  // message. This will un-block the way for later frames to be
137  // buffered.
138  if (p.type == d_begin_frame_m_id) {
140  }
141 
142  // Pack and send the message to the client, then delete the buffer
143  // associated with the message. Send them all reliably. Send them
144  // all using our sender ID.
146  d_sender_id, p.buffer,
147  vrpn_CONNECTION_RELIABLE) != 0) {
148  fprintf(stderr, "vrpn_Imager_Stream_Buffer::mainloop(): Could "
149  "not pack message\n");
150  break;
151  }
152  delete[] const_cast<char *>(p.buffer);
153  }
154  }
155 }
156 
157 /* static */
158 // This method just passes the call on to the virtual function.
160  void *userdata, vrpn_HANDLERPARAM p)
161 {
163  static_cast<vrpn_Imager_Stream_Buffer *>(userdata);
165  return 0;
166 }
167 
168 // Handle got first connection request by (having the second thread) create
169 // a connection to the server and waiting until we get a description message
170 // from the imager server we're listening to. Timeout after a while if the
171 // connection cannot be made or the server does not respond.
172 
174 {
175  // There should be no thread in existence when this call is made.
176  // If there is, kill it and complain.
177  if (d_logging_thread->running()) {
178  struct timeval now;
179  vrpn_gettimeofday(&now, NULL);
181  "handle_got_first_connection: Thread running when it should not be",
182  now, vrpn_TEXT_ERROR);
184  return;
185  }
186 
187  // Reset the shared state before starting the thread running.
189 
190  // Create a thread whose userdata points at the object that
191  // created it. Then call the start function on that thread and wait
192  // for its vrpn_Imager_Remote to receive the info from the remote server
193  // it has connected to. We time out after a few seconds if we don't
194  // get the response, leaving us with a presumably broken connection
195  // to the server.
196  if (!d_logging_thread->go()) {
197  struct timeval now;
198  vrpn_gettimeofday(&now, NULL);
200  "handle_got_first_connection: Failed to start logging thread", now,
202  delete d_logging_thread;
203  d_logging_thread = NULL;
204  return;
205  }
206  struct timeval start, now;
207  vrpn_gettimeofday(&start, NULL);
208  do {
209  const char *channelBuffer = NULL;
211  d_nRows, d_nCols, d_nDepth, d_nChannels, &channelBuffer)) {
212  int i;
213  const char *bufptr = channelBuffer;
214  for (i = 0; i < d_nChannels; i++) {
215  d_channels[i].unbuffer(&bufptr);
216  }
217  delete[] const_cast<char *>(channelBuffer);
218  return;
219  }
220 
221  vrpn_SleepMsecs(1);
222  vrpn_gettimeofday(&now, NULL);
223  } while (vrpn_TimevalDiff(now, start).tv_sec < 3);
224 
225  // Timed out, so we won't be hearing from the server!
226  vrpn_gettimeofday(&now, NULL);
227  send_text_message("handle_got_first_connection: Didn't hear from server.",
228  now, vrpn_TEXT_WARNING);
229 }
230 
231 // Handle dropped last connection on our primary connection by shutting down the
232 // connection to the imager server (killing the logging thread).
234 {
235  if (!stop_logging_thread()) {
236  fprintf(stderr, "vrpn_Imager_Stream_Buffer::handle_dropped_last_"
237  "connection(): Had to kill logging thread\n");
238  }
239 }
240 
241 // Handles a throttle request by passing it on down to the non-blocking
242 // thread to deal with.
244  void *userdata, vrpn_HANDLERPARAM p)
245 {
246  const char *bufptr = p.buffer;
248  static_cast<vrpn_Imager_Stream_Buffer *>(userdata);
249 
250  // Get the requested number of frames from the buffer
251  vrpn_int32 frames_to_send;
252  if (vrpn_unbuffer(&bufptr, &frames_to_send)) {
253  return -1;
254  }
255 
256  me->d_shared_state.set_throttle_request(frames_to_send);
257  return 0;
258 }
259 
260 // The function that is called to become the logging thread. It is passed
261 // a pointer to "this" so that it can acces the object that created it.
262 // The static function basically just unpacks the "this" pointer and
263 // then calls the non-static function.
265  vrpn_ThreadData &threadData)
266 {
268  static_cast<vrpn_Imager_Stream_Buffer *>(threadData.pvUD);
269  me->logging_thread_func();
270 }
271 
272 // Note that it must use semaphores to get at the data that will be shared
273 // between the main thread and itself.
274 // This function does all the work of the logging thread, including all
275 // interactions with the vrpn_Imager_Server connection(s) and the client
276 // object; it forwards information both ways to the main thread that is
277 // communicating with the end-user client connection.
278 // DO NOT CALL VRPN message sends on the client object's connection from
279 // this function or those it calls, because we're not the thread that is
280 // connected to the client object's connection and such calls are not
281 // thread-safe.
282 // Instead, pass the data needed to make the calls to the initial thread.
284 {
285  // Initialize everything to a clean state.
286  d_log_connection = NULL;
287  d_imager_remote = NULL;
288  d_server_dropped_due_to_throttle = 0; // None dropped yet!
289  d_server_frames_to_send = -1; // Send as many as you get
290 
291  // Open a connection to the server object, not asking it to log anything.
292  // (Logging will be started later if we receive a message from our client.)
293  // Create a vrpn_Imager_Remote object and set its callbacks to fill things
294  // into the shared data structures.
295  d_log_connection = open_new_log_connection("", "", "", "");
296  if (d_log_connection == NULL) {
297  fprintf(stderr, "vrpn_Imager_Stream_Buffer::logging_thread_func(): "
298  "Cannot open connection\n");
299  return;
300  }
302  fprintf(stderr, "vrpn_Imager_Stream_Buffer::logging_thread_func(): "
303  "Cannot set up handlers\n");
304  return;
305  }
306 
307  // Keep doing mainloop() on the client object(s) and checking
308  // for commands that we're supposed to issue until we're
309  // told that we're supposed to die. Sleep a little between iterations
310  // to avoid eating CPU time.
311  while (!d_shared_state.time_to_exit()) {
312  // Check to see if the client has sent a new throttling message.
313  // If so, then adjust our state accordingly. Note that we are
314  // duplicating
315  // the effort of the vrpn_Imager_Server base class here; it will still
316  // be
317  // keeping its own shadow copy of these values, but will not be doing
318  // anything
319  // with them because we'll never be calling its send routines. This
320  // duplicates
321  // the code in the handle_throttle_message() in the vrpn_Imager_Server
322  // base
323  // class.
324  vrpn_int32 frames_to_send;
325  if (d_shared_state.get_throttle_request(&frames_to_send)) {
326  // If the requested number of frames is negative, then we set
327  // for unbounded sending. The next time a begin_frame message
328  // arrives, it will start the process going again.
329  if (frames_to_send < 0) {
331 
332  // If we were sending continuously, store the number of frames
333  // to send. Decrement by the number of frames already in the
334  // outgoing buffer, but don't let the number go below zero.
335  }
336  else if (d_server_frames_to_send == -1) {
337  int frames_in_queue = d_shared_state.get_frames_in_queue();
338  if (frames_to_send >= frames_in_queue) {
339  frames_to_send -= frames_in_queue;
340  }
341  d_server_frames_to_send = frames_to_send;
342 
343  // If we already had a throttle limit set, then increment it
344  // by the count.
345  }
346  else {
347  d_server_frames_to_send += frames_to_send;
348  }
349  }
350 
351  // Check to see if we've been asked to create new log files. If we
352  // have,
353  // then attempt to do so. If that works, pass back the names of the
354  // files
355  // created to the initial thread. If it did not work, return empty
356  // log-file
357  // names.
358  char *lil, *lol, *ril, *rol;
359  if (d_shared_state.get_logfile_request(&lil, &lol, &ril, &rol)) {
360  if (make_new_logging_connection(lil, lol, ril, rol)) {
361  d_shared_state.set_logfile_result(lil, lol, ril, rol);
362  }
363  else {
364  d_shared_state.set_logfile_result("", "", "", "");
365  }
366  // Delete the allocated space only if there were return values.
367  delete[] lil;
368  delete[] lol;
369  delete[] ril;
370  delete[] rol;
371  }
372 
373  // Handle all of the messages coming from the server.
374  if (d_imager_remote) {
376  }
377  if (d_log_connection) {
380  }
381 
382  vrpn_SleepMsecs(1);
383  }
384 
385  // Now that we've been told to die, clean up everything and return.
386  if (d_imager_remote) {
387  delete d_imager_remote;
388  d_imager_remote = NULL;
389  }
390  if (d_log_connection) {
392  d_log_connection = NULL;
393  }
394 }
395 
396 /* static */
397 int VRPN_CALLBACK
400 {
402  static_cast<vrpn_Imager_Stream_Buffer *>(pvISB);
403  return me->handle_server_messages(p);
404 }
405 
407  const vrpn_HANDLERPARAM &p)
408 {
409  // Handle begin_frame message very specially, because it has all sorts
410  // of interactions with throttling and missed-frame reporting.
411  if (p.type == d_server_begin_frame_m_id) {
412  // This duplicates code from the send_begin_frame() method in
413  // the vrpn_Imager_Server base class that handles throttling.
414  // It further adds code to handle throttling when the queue to
415  // the initial thread is too full.
416 
417  // If we are throttling frames and the frame count has gone to zero,
418  // then increment the number of frames missed and do not add this
419  // message to the queue.
420  if (d_server_frames_to_send == 0) {
422  return 0;
423  }
424 
425  // If there are too many frames in the queue already,
426  // add one to the number lost due to throttling (which
427  // will prevent region and end-of-frame messages until the next
428  // begin_frame message) and break without forwarding the message.
429  if (d_shared_state.get_frames_in_queue() >= 2) {
431  return 0;
432  }
433 
434  // If we missed some frames due to throttling, but are now
435  // sending frames again, report how many we lost due to
436  // throttling. This is incremented both for client-requested
437  // throttling and to queue-overflow throttling.
439  // We create a new message header and body, using the server's
440  // type IDs, and then transcode and send the message through
441  // the initial connection.
442  vrpn_HANDLERPARAM tp = p;
443  vrpn_float64
444  fbuf[vrpn_CONNECTION_TCP_BUFLEN / sizeof(vrpn_float64)];
445  char *msgbuf = (char *)fbuf;
446  int buflen = sizeof(fbuf);
448 
449  if (vrpn_buffer(&msgbuf, &buflen,
451  fprintf(stderr, "vrpn_Imager_Stream_Buffer::handle_server_"
452  "messages: Can't pack count\n");
453  return -1;
454  }
455  tp.buffer = static_cast<char *>(static_cast<void *>(fbuf));
456  tp.payload_len = sizeof(fbuf) - buflen;
457 
458  if (!transcode_and_send(tp)) {
459  fprintf(stderr, "vrpn_Imager_Stream_Buffer::handle_server_"
460  "messages: Can't send discarded frames "
461  "count\n");
462  return -1;
463  }
464 
466  }
467 
468  // If we are throttling, then decrement the number of frames
469  // left to send.
470  if (d_server_frames_to_send > 0) {
472  }
473 
474  // No throttling going on, so add the message to the outgoing queue and
475  // also increment the count of how many outstanding frames are in the
476  // queue.
477  if (!transcode_and_send(p)) {
478  fprintf(stderr, "vrpn_Imager_Stream_Buffer::handle_server_messages:"
479  " Can't transcode and send\n");
480  return -1;
481  }
483 
484  // Handle the end_frame and all of the region messages in a similar
485  // manner,
486  // dropping them if throttling is going on and passing them on if not.
487  // This duplicates code from the send_end_frame() and the region
488  // send methods in the vrpn_Imager_Server base class that handles
489  // throttling.
490  }
491  else if ((p.type == d_server_end_frame_m_id) ||
492  (p.type == d_server_regionu8_m_id) ||
494  (p.type == d_server_regionu16_m_id) ||
495  (p.type == d_server_regionf32_m_id)) {
496 
497  // If we are discarding frames, do not queue this message.
499  return 0;
500  }
501 
502  // No throttling going on, so add this message to the outgoing queue.
503  if (!transcode_and_send(p)) {
504  fprintf(stderr, "vrpn_Imager_Stream_Buffer::handle_server_messages:"
505  " Can't transcode and send\n");
506  return -1;
507  }
508 
509  // Send these messages on without modification
510  // (Currently, these are description messages and discarded-frame
511  // messages. It also includes the generic pong response and any
512  // text messages.)
513  }
514  else if ((p.type == d_server_description_m_id) ||
516  (p.type == d_server_text_m_id) || (p.type == d_server_pong_m_id)) {
517  if (!transcode_and_send(p)) {
518  fprintf(stderr, "vrpn_Imager_Stream_Buffer::handle_server_messages:"
519  " Can't transcode and send\n");
520  return -1;
521  }
522 
523  // Ignore these messages without passing them on.
524  }
525  else if ((p.type == d_server_ping_m_id)) {
526  return 0;
527 
528  // We need to throw a warning here on unexpected types so that we get
529  // some
530  // warning if additional messages are added. This code is fragile
531  // because it
532  // relies on us knowing the types of base-level and imager messages and
533  // catching
534  // them all. This way, at least we'll know if we miss one.
535  }
536  else {
537  // We create a new message header and body, using the server's
538  // type IDs, and then transcode and send the message through
539  // the initial connection. This is a text message saying that we
540  // got a message of unknown type.
541  vrpn_HANDLERPARAM tp = p;
542  char buffer[2 * sizeof(vrpn_int32) + vrpn_MAX_TEXT_LEN];
543  char msg[vrpn_MAX_TEXT_LEN];
545  tp.buffer = buffer;
546  tp.payload_len = sizeof(buffer);
547  sprintf(msg, "Unknown message type from server: %d",
548  static_cast<int>(p.type));
550  if (!transcode_and_send(tp)) {
551  fprintf(stderr, "vrpn_Imager_Stream_Buffer::handle_server_messages:"
552  " Can't transcode text message\n");
553  return -1;
554  }
555  }
556 
557  return 0;
558 }
559 
560 // Transcode the sender and type fields from the logging server connection to
561 // the initial client connection and pack the resulting message into the queue
562 // from the logging thread to the initial thread. The data buffer is copied;
563 // this space is allocated by the logging thread and must be freed by the
564 // initial thread.
565 // Returns true on success and false on failure. The sender is set to the
566 // d_sender_id of our server object.
568 {
569  // Copy the contents of the buffer to a newly-allocated one that will be
570  // passed to the initial thread.
571  char *newbuf = new char[p.payload_len];
572  if (newbuf == NULL) {
573  fprintf(
574  stderr,
575  "vrpn_Imager_Stream_Buffer::transcode_and_send(): Out of memory\n");
576  return false;
577  }
578  memcpy(newbuf, p.buffer, p.payload_len);
579 
580  // Copy the contents of the handlerparam to a newly-allocated one that will
581  // be passed to the initial thread. Change the sender to match ours, set
582  // the
583  // buffer pointer to the new buffer, and transcode the type.
584  vrpn_HANDLERPARAM newp = p;
585  newp.buffer = newbuf;
586  newp.sender = d_sender_id;
587  newp.type = transcode_type(p.type);
588  if (newp.type == -1) {
589  fprintf(stderr, "vrpn_Imager_Stream_Buffer::transcode_and_send(): "
590  "Unknown type (%d)\n",
591  static_cast<int>(p.type));
592  delete[] newbuf;
593  return false;
594  }
595 
596  // Add the message to the queue of messages going to the initial thread.
598  fprintf(stderr, "vrpn_Imager_Stream_Buffer::transcode_and_send(): "
599  "Can't queue message\n");
600  return false;
601  }
602 
603  return true;
604 }
605 
606 // Transcode the type from the logging thread's connection type to
607 // the initial thread's connection type. Return -1 if we don't
608 // recognize the type.
609 vrpn_int32 vrpn_Imager_Stream_Buffer::transcode_type(vrpn_int32 type)
610 {
612  return d_description_m_id;
613  }
614  else if (type == d_server_begin_frame_m_id) {
615  return d_begin_frame_m_id;
616  }
617  else if (type == d_server_end_frame_m_id) {
618  return d_end_frame_m_id;
619  }
620  else if (type == d_server_discarded_frames_m_id) {
622  }
623  else if (type == d_server_regionu8_m_id) {
624  return d_regionu8_m_id;
625  }
626  else if (type == d_server_regionu12in16_m_id) {
627  return d_regionu12in16_m_id;
628  }
629  else if (type == d_server_regionu16_m_id) {
630  return d_regionu16_m_id;
631  }
632  else if (type == d_server_regionf32_m_id) {
633  return d_regionf32_m_id;
634  }
635  else if (type == d_server_text_m_id) {
636  return d_text_message_id;
637  }
638  else if (type == d_server_ping_m_id) {
639  return d_ping_message_id;
640  }
641  else if (type == d_server_pong_m_id) {
642  return d_pong_message_id;
643  }
644  else {
645  return -1;
646  }
647 }
648 
650  const char *local_in_logfile_name, const char *local_out_logfile_name,
651  const char *remote_in_logfile_name, const char *remote_out_logfile_name)
652 {
653  vrpn_Connection *ret = NULL;
654 
655  // Find the relevant part of the name (skip past last '@'
656  // if there is one); also find the port number.
657  const char *cname = d_imager_server_name;
658  const char *where_at; // Part of name past last '@'
659  if ((where_at = strrchr(cname, '@')) != NULL) {
660  cname = where_at + 1; // Chop off the front of the name
661  }
662 
663  // Pass "true" to force_connection so that it will open a new
664  // connection even if we already have one with that name.
666  where_at, local_in_logfile_name, local_out_logfile_name,
667  remote_in_logfile_name, remote_out_logfile_name, NULL, true);
668  if (!ret || !ret->doing_okay()) {
669  struct timeval now;
670  vrpn_gettimeofday(&now, NULL);
671  fprintf(stderr, "vrpn_Imager_Stream_Buffer::open_new_log_connection: "
672  "Could not create connection (files already exist?)");
673  if (ret) {
674  delete ret;
675  return NULL;
676  }
677  }
678 
679  return ret;
680 }
681 
683  vrpn_Connection *c)
684 {
685  // Create a vrpn_Imager_Remote on this connection and set its callbacks so
686  // that they will do what needs doing; the callbacks point to the
687  // Imager_Stream_Buffer object, not to the imager_remote object; access it
688  // through the member variable pointer.
690  if (d_imager_remote == NULL) {
691  fprintf(stderr, "vrpn_Imager_Stream_Buffer::setup_handlers_for_logging_"
692  "connection(): Cannot create vrpn_Imager_Remote\n");
693  return false;
694  }
697 
698  // Figure out the remote type IDs from the server for the messages we want
699  // to forward. This is really dangerous, because we need to make sure to
700  // explicitly list all the ones we might need. If we forget an important
701  // one (or it gets added later to either the base class or the imager class)
702  // then it won't get forwarded.
704  c->register_message_type("vrpn_Imager Description");
706  c->register_message_type("vrpn_Imager Begin_Frame");
707  d_server_end_frame_m_id = c->register_message_type("vrpn_Imager End_Frame");
709  c->register_message_type("vrpn_Imager Discarded_Frames");
710  d_server_regionu8_m_id = c->register_message_type("vrpn_Imager Regionu8");
711  d_server_regionu16_m_id = c->register_message_type("vrpn_Imager Regionu16");
713  c->register_message_type("vrpn_Imager Regionu12in16");
714  d_server_regionf32_m_id = c->register_message_type("vrpn_Imager Regionf32");
715  d_server_text_m_id = c->register_message_type("vrpn_Base text_message");
716  d_server_ping_m_id = c->register_message_type("vrpn_Base ping_message");
717  d_server_pong_m_id = c->register_message_type("vrpn_Base pong_message");
718 
719  // Set up handlers for the other messages from the server so that they can
720  // be passed on up to the initial thread and on to the client as
721  // appropriate.
722  // Be sure to strip the "@" part off the device name before registering the
723  // sender
724  // so that it is the same as the one used by the d_imager_remote.
725  c->register_handler(
728 
729  return true;
730 }
731 
733  vrpn_Connection *c)
734 {
735  if (!d_imager_remote) {
736  fprintf(stderr, "vrpn_Imager_Stream_Buffer::teardown_handlers_for_"
737  "logging_connection(): No imager remote\n");
738  return false;
739  }
741  this, handle_image_description) != 0) {
742  fprintf(stderr, "vrpn_Imager_Stream_Buffer::teardown_handlers_for_"
743  "logging_connection(): Cannot unregister handler\n");
744  return false;
745  }
746 
747  // Tear down handlers for the other messages from the server.
751 
752  delete d_imager_remote;
753  d_imager_remote = NULL;
754  return true;
755 }
756 
758  const char *local_in_logfile_name, const char *local_out_logfile_name,
759  const char *remote_in_logfile_name, const char *remote_out_logfile_name)
760 {
761  // Open a new connection to do logging on before deleting the old one so
762  // that we keep at least one connection open to the server at all time.
763  // This will prevent it from doing its "dropped last connection" things
764  // which will include resetting the imager server.
765  vrpn_Connection *new_log_connection = open_new_log_connection(
766  local_in_logfile_name, local_out_logfile_name, remote_in_logfile_name,
767  remote_out_logfile_name);
768  if (new_log_connection == NULL) {
769  fprintf(stderr, "vrpn_Imager_Stream_Buffer::make_new_logging_"
770  "connection(): Cannot open connection\n");
771  return false;
772  }
773 
774  // Unhook the callbacks from the existing logging connection so that
775  // we don't end up with two callbacks for each message.
777  fprintf(stderr, "vrpn_Imager_Stream_Buffer::make_new_logging_"
778  "connection(): Cannot teardown connection\n");
779  return false;
780  }
781 
782  // Hook the callbacks up to the new connection so that we will get reports
783  // from the server.
784  if (!setup_handlers_for_logging_connection(new_log_connection)) {
785  fprintf(stderr, "vrpn_Imager_Stream_Buffer::make_new_logging_"
786  "connection(): Cannot setup connection\n");
787  return false;
788  }
789 
790  // Mainloop the new connection object until it becomes connected or we
791  // time out. If we time out, then put things back on the old connection
792  // and tell the thread it is time to self-destruct. The way we check
793  // for connected cannot be just that the connection's connected() method
794  // returns true (because our end can be marked connected before the other
795  // end decides it has complete the connection. Rather, we check to see
796  // that we've got a new description report from the server -- indicating
797  // that it has seen the new report. This also lets us know that the old
798  // log file will have accumulated all images up to the new report, so we
799  // can shut it off without losing any images in the switch to the new
800  // log file (there may be duplicates, but not losses).
801  struct timeval start, now;
802  vrpn_gettimeofday(&start, NULL);
803  now = start;
806  (vrpn_TimevalDiff(now, start).tv_sec < 3)) {
807  new_log_connection->mainloop(); // Enable connection set-up to occur
808  new_log_connection->save_log_so_far();
809  d_log_connection->mainloop(); // Eat up (and log) any incoming messages
811  vrpn_gettimeofday(&now, NULL);
812  vrpn_SleepMsecs(1);
813  };
815  fprintf(stderr, "vrpn_Imager_Stream_Buffer::make_new_logging_"
816  "connection(): Could not connect new logging "
817  "connection\n");
818  teardown_handlers_for_logging_connection(new_log_connection);
820  new_log_connection->removeReference();
822  return false;
823  }
824 
825  // Delete the old connection object by reducing its reference count.
827 
828  // Set up to use the new connection
829  d_log_connection = new_log_connection;
830  return true;
831 }
832 
834  const char *local_in_logfile_name, const char *local_out_logfile_name,
835  const char *remote_in_logfile_name, const char *remote_out_logfile_name)
836 {
837  // Request that the logging thread start new logs.
839  local_in_logfile_name, local_out_logfile_name, remote_in_logfile_name,
840  remote_out_logfile_name);
841 
842  // Wait until we hear back from the logging thread or time out;
843  // return empty if timeout and the strings we got back if not.
844  // Remember to deallocated the memory if we got a response.
845  struct timeval start, now;
846  vrpn_gettimeofday(&start, NULL);
847  do {
848  char *lil, *lol, *ril, *rol;
849  if (d_shared_state.get_logfile_result(&lil, &lol, &ril, &rol)) {
850  send_report_logging(lil, lol, ril, rol);
851  delete[] lil;
852  delete[] lol;
853  delete[] ril;
854  delete[] rol;
855  return;
856  }
857  vrpn_SleepMsecs(1);
858  vrpn_gettimeofday(&now, NULL);
859  } while (vrpn_TimevalDiff(now, start).tv_sec < 2);
860 
861  // Timeout, report failure of logging by saying that there are empty log
862  // file names.
863  send_report_logging("", "", "", "");
864 }
865 
867 {
868  char *local_in;
869  char *local_out;
870  char *remote_in;
871  char *remote_out;
872  d_shared_state.get_logfile_names(&local_in, &local_out, &remote_in,
873  &remote_out);
874  send_report_logging(local_in, local_out, remote_in, remote_out);
875  if (local_in) delete[] local_in;
876  if (local_out) delete[] local_out;
877  if (remote_in) delete[] remote_in;
878  if (remote_out) delete[] remote_out;
879 }
880 
881 /* Static */
882 // We've gotten a new imager description, so fill it into the shared data
883 // structure
884 // so that the parent object can hear about it.
886  void *pvISB, const struct timeval msg_time)
887 {
889  static_cast<vrpn_Imager_Stream_Buffer *>(pvISB);
890 
891  // Pack up description messages for all of the channels into a buffer that
892  // is at
893  // least large enough to hold them all.
894  // msgbuf must be float64-aligned!
895  vrpn_float64 *fbuf =
896  new vrpn_float64[vrpn_CONNECTION_TCP_BUFLEN / sizeof(vrpn_float64)];
897  char *buffer = static_cast<char *>(static_cast<void *>(fbuf));
898  if (buffer == NULL) {
899  fprintf(stderr, "vrpn_Imager_Stream_Buffer::handle_image_description():"
900  " Out of memory\n");
901  me->d_shared_state.time_to_exit(true);
902  return;
903  }
904  int i;
905  char *bufptr = buffer;
906  vrpn_int32 buflen = sizeof(vrpn_float64) * vrpn_CONNECTION_TCP_BUFLEN /
907  sizeof(vrpn_float64);
908  for (i = 0; i < me->d_imager_remote->nChannels(); i++) {
909  me->d_imager_remote->channel(i)->buffer(&bufptr, &buflen);
910  }
911 
915  buffer);
916 
917  // We've gotten a description report on the new connection, so we're ready
918  // to drop the old connection.
920 }
921 
922 // Stop the logging thread function, cleanly if possible. Returns true if
923 // the function stopped cleanly, false if it had to be killed.
925 {
926  // Set the flag telling the logging thread to stop.
928 
929  // Wait for up to three seconds for the logging thread to die a clean death.
930  // If it does, return true.
931  struct timeval start, now;
932  vrpn_gettimeofday(&start, NULL);
933  do {
934  if (!d_logging_thread->running()) {
935  return true;
936  }
937  vrpn_SleepMsecs(1);
938  vrpn_gettimeofday(&now, NULL);
939  } while (vrpn_TimevalDiff(now, start).tv_sec < 3);
940 
942  return false;
943 }
vrpn_Imager_Stream_Buffer::handle_image_description
static void VRPN_CALLBACK handle_image_description(void *pvISB, const struct timeval msg_time)
Definition: vrpn_Imager_Stream_Buffer.C:885
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::d_nChannels
vrpn_int32 d_nChannels
Definition: vrpn_Imager.h:131
vrpn_BaseClassUnique::register_autodeleted_handler
int register_autodeleted_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Registers a handler with the connection, and remembers to delete at destruction.
Definition: vrpn_BaseClass.C:503
vrpn_Connection::pack_message
virtual int pack_message(vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 class_of_service)
Pack a message that will be sent the next time mainloop() is called. Turn off the RELIABLE flag if yo...
Definition: vrpn_Connection.C:4632
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_Buffer::static_handle_got_first_connection
static int VRPN_CALLBACK static_handle_got_first_connection(void *userdata, vrpn_HANDLERPARAM p)
Definition: vrpn_Imager_Stream_Buffer.C:159
vrpn_Imager::d_regionu16_m_id
vrpn_int32 d_regionu16_m_id
Definition: vrpn_Imager.h:150
vrpn_Imager::d_regionu12in16_m_id
vrpn_int32 d_regionu12in16_m_id
Definition: vrpn_Imager.h:147
vrpn_BaseClass.h
vrpn_Imager::d_channels
vrpn_Imager_Channel d_channels[vrpn_IMAGER_MAX_CHANNELS]
Definition: vrpn_Imager.h:132
vrpn_Imager::d_end_frame_m_id
vrpn_int32 d_end_frame_m_id
Definition: vrpn_Imager.h:139
vrpn_BaseClassUnique::d_ping_message_id
vrpn_int32 d_ping_message_id
Ask the server if they are there.
Definition: vrpn_BaseClass.h:230
vrpn_MAX_TEXT_LEN
const unsigned vrpn_MAX_TEXT_LEN
Definition: vrpn_BaseClass.h:105
vrpn_Thread::running
bool running()
Definition: vrpn_Shared.C:1308
vrpn_get_connection_by_name
vrpn_Connection * vrpn_get_connection_by_name(const char *cname, const char *local_in_logfile_name, const char *local_out_logfile_name, const char *remote_in_logfile_name, const char *remote_out_logfile_name, const char *NIC_IPaddress, bool force_connection)
Create a client connection of arbitrary type (VRPN UDP/TCP, TCP, File, Loopback, MPI).
Definition: vrpn_Connection.C:5277
vrpn_Imager_Stream_Buffer::setup_handlers_for_logging_connection
bool setup_handlers_for_logging_connection(vrpn_Connection *c)
Definition: vrpn_Imager_Stream_Buffer.C:682
vrpn_Imager_Stream_Buffer::mainloop
virtual void mainloop(void)
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition: vrpn_Imager_Stream_Buffer.C:98
vrpn_Imager_Stream_Buffer::transcode_type
vrpn_int32 transcode_type(vrpn_int32 type)
Definition: vrpn_Imager_Stream_Buffer.C:609
vrpn_Imager_Stream_Shared_State::init
void init(void)
Definition: vrpn_Imager_Stream_Buffer.h:115
vrpn_Imager_Stream_Buffer::stop_logging_thread
bool stop_logging_thread(void)
Definition: vrpn_Imager_Stream_Buffer.C:924
vrpn_Imager_Stream_Buffer::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)
Definition: vrpn_Imager_Stream_Buffer.C:833
vrpn_Imager_Stream_Buffer::open_new_log_connection
vrpn_Connection * open_new_log_connection(const char *local_in_logfile_name, const char *local_out_logfile_name, const char *remote_in_logfile_name, const char *remote_out_logfile_name)
Definition: vrpn_Imager_Stream_Buffer.C:649
vrpn_Thread
Definition: vrpn_Shared.h:558
vrpn_Imager_Stream_Buffer::static_handle_server_messages
static int VRPN_CALLBACK static_handle_server_messages(void *pvISB, vrpn_HANDLERPARAM p)
Definition: vrpn_Imager_Stream_Buffer.C:398
vrpn_Imager_Stream_Buffer::teardown_handlers_for_logging_connection
bool teardown_handlers_for_logging_connection(vrpn_Connection *c)
Definition: vrpn_Imager_Stream_Buffer.C:732
vrpn_Imager_Stream_Buffer::d_log_connection
vrpn_Connection * d_log_connection
Definition: vrpn_Imager_Stream_Buffer.h:653
vrpn_Imager_Stream_Buffer.h
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_Imager_Stream_Buffer::handle_dropped_last_connection
virtual void handle_dropped_last_connection(void)
Definition: vrpn_Imager_Stream_Buffer.C:233
vrpn_Imager_Stream_Buffer::d_server_ping_m_id
vrpn_int32 d_server_ping_m_id
Definition: vrpn_Imager_Stream_Buffer.h:710
vrpn_Imager_Stream_Buffer::make_new_logging_connection
bool make_new_logging_connection(const char *local_in_logfile_name, const char *local_out_logfile_name, const char *remote_in_logfile_name, const char *remote_out_logfile_name)
Definition: vrpn_Imager_Stream_Buffer.C:757
vrpn_BaseClassUnique::userdata
void * userdata
Definition: vrpn_BaseClass.h:287
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::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_Imager_Stream_Buffer::d_server_regionf32_m_id
vrpn_int32 d_server_regionf32_m_id
Definition: vrpn_Imager_Stream_Buffer.h:707
vrpn_got_first_connection
const char * vrpn_got_first_connection
These are the strings that define the system-generated message types that tell when connections are r...
Definition: vrpn_Connection.C:184
vrpn_Connection::save_log_so_far
virtual int save_log_so_far()
Save any messages on any endpoints which have been logged so far.
Definition: vrpn_Connection.C:4735
vrpn_Imager::d_regionu8_m_id
vrpn_int32 d_regionu8_m_id
Definition: vrpn_Imager.h:145
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_HANDLERPARAM::payload_len
vrpn_int32 payload_len
Definition: vrpn_Connection.h:48
vrpn_Imager_Stream_Buffer::d_server_regionu16_m_id
vrpn_int32 d_server_regionu16_m_id
Definition: vrpn_Imager_Stream_Buffer.h:705
vrpn_CONNECTION_TCP_BUFLEN
const int vrpn_CONNECTION_TCP_BUFLEN
Definition: vrpn_Connection.h:95
vrpn_Imager_Remote::channel
const vrpn_Imager_Channel * channel(unsigned chanNum) const
Accessors for the member variables: can be queried in the handler for object changes.
Definition: vrpn_Imager.C:1202
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_BaseClassUnique::d_text_message_id
vrpn_int32 d_text_message_id
ID for text messages.
Definition: vrpn_BaseClass.h:229
vrpn_Imager_Stream_Buffer::handle_request_logging_status
virtual void handle_request_logging_status()
Definition: vrpn_Imager_Stream_Buffer.C:866
vrpn_Thread::go
bool go()
Definition: vrpn_Shared.C:1237
vrpn_unbuffer
VRPN_API int vrpn_unbuffer(const char **buffer, timeval *t)
Utility routine for taking a struct timeval from a buffer that was sent as a message.
Definition: vrpn_Shared.C:312
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_Imager_Stream_Buffer::transcode_and_send
bool transcode_and_send(const vrpn_HANDLERPARAM &p)
Definition: vrpn_Imager_Stream_Buffer.C:567
vrpn_BaseClassUnique::d_connection
vrpn_Connection * d_connection
Connection that this object talks to.
Definition: vrpn_BaseClass.h:224
vrpn_BaseClassUnique::encode_text_message_to_buffer
static int encode_text_message_to_buffer(char *buf, vrpn_TEXT_SEVERITY severity, vrpn_uint32 level, const char *msg)
Encodes the body of the text message into a buffer, preparing for sending.
Definition: vrpn_BaseClass.C:534
vrpn_HANDLERPARAM::buffer
const char * buffer
Definition: vrpn_Connection.h:49
vrpn_Connection::register_message_type
virtual vrpn_int32 register_message_type(const char *name)
Definition: vrpn_Connection.C:5074
vrpn_Imager_Stream_Shared_State::decrement_frames_in_queue
vrpn_int32 decrement_frames_in_queue(void)
Definition: vrpn_Imager_Stream_Buffer.h:455
vrpn_TEXT_ERROR
@ vrpn_TEXT_ERROR
Definition: vrpn_BaseClass.h:103
vrpn_Imager_Stream_Buffer::handle_got_first_connection
virtual void handle_got_first_connection(void)
Definition: vrpn_Imager_Stream_Buffer.C:173
vrpn_TimevalDiff
timeval vrpn_TimevalDiff(const timeval &tv1, const timeval &tv2)
Definition: vrpn_Shared.C:92
vrpn_CONNECTION_RELIABLE
const vrpn_uint32 vrpn_CONNECTION_RELIABLE
Classes of service for messages, specify multiple by ORing them together Priority of satisfying these...
Definition: vrpn_Connection.h:120
vrpn_Imager_Stream_Buffer::vrpn_Imager_Stream_Buffer
vrpn_Imager_Stream_Buffer(const char *name, const char *imager_server_name, vrpn_Connection *c)
Definition: vrpn_Imager_Stream_Buffer.C:6
vrpn_SleepMsecs
void vrpn_SleepMsecs(double dMsecs)
Definition: vrpn_Shared.C:157
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_Imager::d_discarded_frames_m_id
vrpn_int32 d_discarded_frames_m_id
Definition: vrpn_Imager.h:141
vrpn_HANDLERPARAM
This structure is what is passed to a vrpn_Connection message callback.
Definition: vrpn_Connection.h:44
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_TEXT_WARNING
@ vrpn_TEXT_WARNING
Definition: vrpn_BaseClass.h:102
vrpn_Connection::unregister_handler
virtual int unregister_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Definition: vrpn_Connection.C:5206
vrpn_BaseClassUnique::d_sender_id
vrpn_int32 d_sender_id
Sender ID registered with the connection.
Definition: vrpn_BaseClass.h:228
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::logging_thread_func
void logging_thread_func(void)
Definition: vrpn_Imager_Stream_Buffer.C:283
vrpn_ThreadData::pvUD
void * pvUD
Definition: vrpn_Shared.h:549
vrpn_Imager_Stream_Buffer::d_server_regionu8_m_id
vrpn_int32 d_server_regionu8_m_id
Definition: vrpn_Imager_Stream_Buffer.h:700
vrpn_Imager::d_nDepth
vrpn_int32 d_nDepth
Definition: vrpn_Imager.h:130
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_Imager_Remote::register_description_handler
virtual int register_description_handler(void *userdata, vrpn_IMAGERDESCRIPTIONHANDLER handler)
Register a handler for when the object's description changes (if desired).
Definition: vrpn_Imager.h:643
vrpn_Connection::mainloop
virtual int mainloop(const struct timeval *timeout=NULL)=0
Call each time through program main loop to handle receiving any incoming messages and sending any pa...
vrpn_HANDLERPARAM::msg_time
struct timeval msg_time
Definition: vrpn_Connection.h:47
vrpn_Imager_Server::send_description
bool send_description(void)
Sends a description of the imager so the remote can process the region messages.
Definition: vrpn_Imager.C:1045
vrpn_Connection
Generic connection class not specific to the transport mechanism.
Definition: vrpn_Connection.h:510
vrpn_ANY_TYPE
const int vrpn_ANY_TYPE
vrpn_ANY_TYPE can be used to register callbacks for any USER type of message from a given sender....
Definition: vrpn_Connection.h:82
vrpn_Imager_Stream_Buffer::d_imager_remote
vrpn_Imager_Remote * d_imager_remote
Definition: vrpn_Imager_Stream_Buffer.h:683
vrpn_Imager::nRows
vrpn_int32 nRows(void) const
Definition: vrpn_Imager.h:122
vrpn_Imager_Stream_Buffer::d_server_frames_to_send
vrpn_int32 d_server_frames_to_send
Definition: vrpn_Imager_Stream_Buffer.h:735
vrpn_Imager::d_nCols
vrpn_int32 d_nCols
Definition: vrpn_Imager.h:129
vrpn_gettimeofday
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:89
vrpn_Imager_Stream_Buffer::d_logging_thread
vrpn_Thread * d_logging_thread
Definition: vrpn_Imager_Stream_Buffer.h:630
vrpn_Imager::d_regionf32_m_id
vrpn_int32 d_regionf32_m_id
Definition: vrpn_Imager.h:152
vrpn_Imager_Stream_Buffer::d_shared_state
vrpn_Imager_Stream_Shared_State d_shared_state
Definition: vrpn_Imager_Stream_Buffer.h:617
vrpn_ANY_SENDER
const int vrpn_ANY_SENDER
vrpn_ANY_SENDER can be used to register callbacks on a given message type from any sender.
Definition: vrpn_Connection.h:77
vrpn_Imager_Remote::mainloop
virtual void mainloop(void)
XXX It could be nice to let the user specify separate callbacks for.
Definition: vrpn_Imager.C:1194
vrpn_Imager::nChannels
vrpn_int32 nChannels(void) const
Definition: vrpn_Imager.h:125
vrpn_Imager::d_begin_frame_m_id
vrpn_int32 d_begin_frame_m_id
Definition: vrpn_Imager.h:137
vrpn_Connection::register_sender
virtual vrpn_int32 register_sender(const char *name)
Get a token to use for the string name of the sender or type. Remember to check for -1 meaning failur...
Definition: vrpn_Connection.C:5032
vrpn_Imager_Stream_Buffer
Definition: vrpn_Imager_Stream_Buffer.h:548
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::d_throttle_frames_m_id
vrpn_int32 d_throttle_frames_m_id
Definition: vrpn_Imager.h:143
vrpn_Imager_Channel::buffer
bool buffer(char **insertPt, vrpn_int32 *buflen) const
Definition: vrpn_Imager.h:80
vrpn_Imager_Remote::unregister_description_handler
virtual int unregister_description_handler(void *userdata, vrpn_IMAGERDESCRIPTIONHANDLER handler)
Definition: vrpn_Imager.h:649
vrpn_Imager_Stream_Buffer::~vrpn_Imager_Stream_Buffer
virtual ~vrpn_Imager_Stream_Buffer()
Definition: vrpn_Imager_Stream_Buffer.C:89
vrpn_Imager::d_description_m_id
vrpn_int32 d_description_m_id
Definition: vrpn_Imager.h:135
vrpn_Imager::nDepth
vrpn_int32 nDepth(void) const
Definition: vrpn_Imager.h:124
vrpn_HANDLERPARAM::type
vrpn_int32 type
Definition: vrpn_Connection.h:45
vrpn_Connection::removeReference
void removeReference()
Definition: vrpn_Connection.C:5020
vrpn_Imager_Stream_Buffer::handle_server_messages
int handle_server_messages(const vrpn_HANDLERPARAM &p)
Definition: vrpn_Imager_Stream_Buffer.C:406
vrpn_buffer
VRPN_API int vrpn_buffer(char **insertPt, vrpn_int32 *buflen, const timeval t)
Utility routine for placing a timeval struct into a buffer that is to be sent as a message.
Definition: vrpn_Shared.C:241
vrpn_Imager_Stream_Buffer::static_handle_throttle_message
static int VRPN_CALLBACK static_handle_throttle_message(void *userdata, vrpn_HANDLERPARAM p)
Definition: vrpn_Imager_Stream_Buffer.C:243
vrpn_Connection::doing_okay
virtual vrpn_bool doing_okay(void) const
Returns vrpn_true if the connection is okay, vrpn_false if not.
Definition: vrpn_Connection.C:5222
vrpn_Imager_Stream_Buffer::static_logging_thread_func
static void static_logging_thread_func(vrpn_ThreadData &threadData)
Definition: vrpn_Imager_Stream_Buffer.C:264
vrpn_Imager_Channel::unbuffer
bool unbuffer(const char **buffer)
Definition: vrpn_Imager.h:96
vrpn_BaseClassUnique::send_text_message
int send_text_message(const char *msg, struct timeval timestamp, vrpn_TEXT_SEVERITY type=vrpn_TEXT_NORMAL, vrpn_uint32 level=0)
Sends a NULL-terminated text message from the device d_sender_id.
Definition: vrpn_BaseClass.C:568
vrpn_Imager_Stream_Shared_State::set_throttle_request
void set_throttle_request(vrpn_int32 throttle_count)
Definition: vrpn_Imager_Stream_Buffer.h:428
vrpn_Thread::kill
bool kill()
Definition: vrpn_Shared.C:1268
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_copy_service_name
char * vrpn_copy_service_name(const char *fullname)
Definition: vrpn_Connection.C:6335
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_HANDLERPARAM::sender
vrpn_int32 sender
Definition: vrpn_Connection.h:46
vrpn_Auxiliary_Logger_Server::send_report_logging
bool send_report_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)
Definition: vrpn_Auxiliary_Logger.h:91
vrpn_Imager::d_nRows
vrpn_int32 d_nRows
Definition: vrpn_Imager.h:125
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_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_BaseClassUnique::d_pong_message_id
vrpn_int32 d_pong_message_id
Server telling that it is there.
Definition: vrpn_BaseClass.h:231
vrpn_Connection::register_handler
virtual int register_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Set up (or remove) a handler for a message of a given type. Optionally, specify which sender to handl...
Definition: vrpn_Connection.C:5199
vrpn_Imager_Server
Definition: vrpn_Imager.h:156
vrpn_Auxiliary_Logger_Server
Definition: vrpn_Auxiliary_Logger.h:65
vrpn_BaseClassUnique::type
vrpn_int32 type
Definition: vrpn_BaseClass.h:286
vrpn_Imager::nCols
vrpn_int32 nCols(void) const
Definition: vrpn_Imager.h:123
vrpn_Imager_Stream_Shared_State::get_throttle_request
bool get_throttle_request(vrpn_int32 *throttle_count)
Definition: vrpn_Imager_Stream_Buffer.h:417
vrpn_Imager_Stream_Shared_State::increment_frames_in_queue
vrpn_int32 increment_frames_in_queue(void)
Definition: vrpn_Imager_Stream_Buffer.h:447
vrpn_BaseClassUnique::server_mainloop
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
Definition: vrpn_BaseClass.C:603
vrpn_Imager_Stream_Buffer::d_imager_server_name
char * d_imager_server_name
Definition: vrpn_Imager_Stream_Buffer.h:646