g_flushpl.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /* This file is part of the GNU plotutils package. Copyright (C) 1995,
  2. 1996, 1997, 1998, 1999, 2000, 2005, 2008, Free Software Foundation, Inc.
  3. The GNU plotutils package is free software. You may redistribute it
  4. and/or modify it under the terms of the GNU General Public License as
  5. published by the Free Software foundation; either version 2, or (at your
  6. option) any later version.
  7. The GNU plotutils package is distributed in the hope that it will be
  8. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. General Public License for more details.
  11. You should have received a copy of the GNU General Public License along
  12. with the GNU plotutils package; see the file COPYING. If not, write to
  13. the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor,
  14. Boston, MA 02110-1301, USA. */
  15. /* This file contains the flushpl method, which is a GNU extension to
  16. libplot. It flushes (i.e. pushes onward) all plot commands sent to the
  17. graphics device. */
  18. /* This file also contains the internal _pl_g_flush_plotter_outstreams()
  19. method, which should be invoked by any Plotter that forks an auxiliary
  20. process. (E.g., an XPlotter forks off an auxiliary process when
  21. closepl() is invoked, to manage its `spun-off' window.) */
  22. #include "sys-defines.h"
  23. #include "extern.h"
  24. #ifdef MSDOS
  25. #include <unistd.h> /* for fsync() */
  26. #endif
  27. /* Mutex for locking _plotters[] and _plotters_len. Defined in
  28. g_defplot.c. */
  29. #ifdef PTHREAD_SUPPORT
  30. #ifdef HAVE_PTHREAD_H
  31. extern pthread_mutex_t _plotters_mutex;
  32. #endif
  33. #endif
  34. int
  35. _API_flushpl (S___(Plotter *_plotter))
  36. {
  37. int retval = 0;
  38. if (!_plotter->data->open)
  39. {
  40. _plotter->error (R___(_plotter)
  41. "flushpl: invalid operation");
  42. return -1;
  43. }
  44. switch ((int)_plotter->data->output_model)
  45. {
  46. case (int)PL_OUTPUT_NONE:
  47. /* Plotter doesn't do any output, so do nothing */
  48. break;
  49. case (int)PL_OUTPUT_ONE_PAGE:
  50. case (int)PL_OUTPUT_ONE_PAGE_AT_A_TIME:
  51. case (int)PL_OUTPUT_PAGES_ALL_AT_ONCE:
  52. /* Plotter may have an output stream that can be flushed. Should
  53. really distinguish here between Plotters that write graphics in
  54. real time, and those that wait until the end of a page, or of all
  55. pages, before writing graphics. */
  56. if (_plotter->data->outfp)
  57. {
  58. if (fflush(_plotter->data->outfp) < 0
  59. #ifdef MSDOS
  60. /* data can be caught in DOS buffers, so do an fsync() too */
  61. || fsync (_plotter->data->outfp) < 0
  62. #endif
  63. )
  64. retval = -1;
  65. }
  66. #ifdef LIBPLOTTER
  67. if (_plotter->data->outstream)
  68. {
  69. _plotter->data->outstream->flush ();
  70. if (!(*(_plotter->data->outstream)))
  71. retval = -1;
  72. }
  73. #endif
  74. break;
  75. case (int)PL_OUTPUT_VIA_CUSTOM_ROUTINES:
  76. case (int)PL_OUTPUT_VIA_CUSTOM_ROUTINES_IN_REAL_TIME:
  77. case (int)PL_OUTPUT_VIA_CUSTOM_ROUTINES_TO_NON_STREAM:
  78. /* Plotter does its own output, so invoke Plotter-specific flush
  79. method */
  80. if (_plotter->flush_output (S___(_plotter)) == false)
  81. retval = -1;
  82. break;
  83. default: /* shouldn't happen */
  84. break;
  85. }
  86. if (retval < 0)
  87. _plotter->error (R___(_plotter) "the output stream is jammed");
  88. return retval;
  89. }
  90. /* An internal method that's called when any Plotter that does its own
  91. output to a non-stream is flushed. Actually, this generic version does
  92. nothing; it'll need to be overridden by any Plotter that wishes to make
  93. use of this feature. Return value indicates success. */
  94. bool
  95. _pl_g_flush_output (S___(Plotter *_plotter))
  96. {
  97. return true;
  98. }
  99. /* Flush output streams for all Plotters. Plotters that fork when the
  100. closepl() operation is invoked should call this before forking.
  101. This code is messy, because there are four cases to cover, and in the
  102. final three, the global variables _plotters[] and _plotters_len need to
  103. be locked and unlocked. */
  104. void
  105. _pl_g_flush_plotter_outstreams (S___(Plotter *_plotter))
  106. {
  107. #ifndef LIBPLOTTER
  108. #ifdef HAVE_NULL_FLUSH
  109. fflush ((FILE *)NULL);
  110. #else /* not HAVE_NULL_FLUSH */
  111. int i;
  112. #ifdef PTHREAD_SUPPORT
  113. #ifdef HAVE_PTHREAD_H
  114. pthread_mutex_lock (&_plotters_mutex);
  115. #endif
  116. #endif
  117. for (i = 0; i < _plotters_len; i++)
  118. if (_plotters[i])
  119. {
  120. if (_plotters[i]->data->outfp)
  121. fflush (_plotters[i]->data->outfp);
  122. if (_plotters[i]->data->errfp)
  123. fflush (_plotters[i]->data->errfp);
  124. }
  125. #ifdef PTHREAD_SUPPORT
  126. #ifdef HAVE_PTHREAD_H
  127. pthread_mutex_unlock (&_plotters_mutex);
  128. #endif
  129. #endif
  130. #endif /* not HAVE_NULL_FLUSH */
  131. #else /* LIBPLOTTER */
  132. int i;
  133. #ifdef PTHREAD_SUPPORT
  134. #ifdef HAVE_PTHREAD_H
  135. pthread_mutex_lock (&_plotters_mutex);
  136. #endif
  137. #endif
  138. #ifdef HAVE_NULL_FLUSH
  139. fflush ((FILE *)NULL);
  140. for (i = 0; i < _plotters_len; i++)
  141. if (_plotters[i])
  142. {
  143. if (_plotters[i]->data->outstream)
  144. _plotters[i]->data->outstream->flush ();
  145. if (_plotters[i]->data->errstream)
  146. _plotters[i]->data->errstream->flush ();
  147. }
  148. #else /* not HAVE_NULL_FLUSH */
  149. for (i = 0; i < _plotters_len; i++)
  150. if (_plotters[i])
  151. {
  152. if (_plotters[i]->data->outfp)
  153. fflush (_plotters[i]->data->outfp);
  154. if (_plotters[i]->data->errfp)
  155. fflush (_plotters[i]->data->errfp);
  156. if (_plotters[i]->data->outstream)
  157. _plotters[i]->data->outstream->flush ();
  158. if (_plotters[i]->data->errstream)
  159. _plotters[i]->data->errstream->flush ();
  160. }
  161. #endif /* not HAVE_NULL_FLUSH */
  162. #ifdef PTHREAD_SUPPORT
  163. #ifdef HAVE_PTHREAD_H
  164. pthread_mutex_unlock (&_plotters_mutex);
  165. #endif
  166. #endif
  167. #endif /* LIBPLOTTER */
  168. }