/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/common/execcmn.cpp
ViewVC logotype

Annotation of /trunk/3rdparty/wxWidgets/src/common/execcmn.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 4 months ago) by william
File size: 3905 byte(s)
committing r3113 initial commit again...
1 william 31 ///////////////////////////////////////////////////////////////////////////////
2     // Name: common/wxexec.cpp
3     // Purpose: defines wxStreamTempInputBuffer which is used by Unix and MSW
4     // implementations of wxExecute; this file is only used by the
5     // library and never by the user code
6     // Author: Vadim Zeitlin
7     // Modified by:
8     // Created: 20.08.02
9     // RCS-ID: $Id: execcmn.cpp 35289 2005-08-23 23:12:48Z VZ $
10     // Copyright: (c) 2002 Vadim Zeitlin <vadim@wxwindows.org>
11     // Licence: wxWindows licence
12     ///////////////////////////////////////////////////////////////////////////////
13    
14     #ifndef _WX_WXEXEC_CPP_
15     #define _WX_WXEXEC_CPP_
16    
17     // this file should never be compiled directly, just included by other code
18     #ifndef _WX_USED_BY_WXEXECUTE_
19     #error "You should never directly build this file!"
20     #endif
21    
22     // ----------------------------------------------------------------------------
23     // wxStreamTempInputBuffer
24     // ----------------------------------------------------------------------------
25    
26     /*
27     wxStreamTempInputBuffer is a hack which we need to solve the problem of
28     executing a child process synchronously with IO redirecting: when we do
29     this, the child writes to a pipe we open to it but when the pipe buffer
30     (which has finite capacity, e.g. commonly just 4Kb) becomes full we have to
31     read data from it because the child blocks in its write() until then and if
32     it blocks we are never going to return from wxExecute() so we dead lock.
33    
34     So here is the fix: we now read the output as soon as it appears into a temp
35     buffer (wxStreamTempInputBuffer object) and later just stuff it back into
36     the stream when the process terminates. See supporting code in wxExecute()
37     itself as well.
38    
39     Note that this is horribly inefficient for large amounts of output (count
40     the number of times we copy the data around) and so a better API is badly
41     needed! However it's not easy to devise a way to do this keeping backwards
42     compatibility with the existing wxExecute(wxEXEC_SYNC)...
43     */
44    
45     class wxStreamTempInputBuffer
46     {
47     public:
48     wxStreamTempInputBuffer();
49    
50     // call to associate a stream with this buffer, otherwise nothing happens
51     // at all
52     void Init(wxPipeInputStream *stream);
53    
54     // check for input on our stream and cache it in our buffer if any
55     void Update();
56    
57     ~wxStreamTempInputBuffer();
58    
59     private:
60     // the stream we're buffering, if NULL we don't do anything at all
61     wxPipeInputStream *m_stream;
62    
63     // the buffer of size m_size (NULL if m_size == 0)
64     void *m_buffer;
65    
66     // the size of the buffer
67     size_t m_size;
68    
69     DECLARE_NO_COPY_CLASS(wxStreamTempInputBuffer)
70     };
71    
72     inline wxStreamTempInputBuffer::wxStreamTempInputBuffer()
73     {
74     m_stream = NULL;
75     m_buffer = NULL;
76     m_size = 0;
77     }
78    
79     inline void wxStreamTempInputBuffer::Init(wxPipeInputStream *stream)
80     {
81     m_stream = stream;
82     }
83    
84     inline
85     void wxStreamTempInputBuffer::Update()
86     {
87     if ( m_stream && m_stream->CanRead() )
88     {
89     // realloc in blocks of 4Kb: this is the default (and minimal) buffer
90     // size of the Unix pipes so it should be the optimal step
91     //
92     // NB: don't use "static int" in this inline function, some compilers
93     // (e.g. IBM xlC) don't like it
94     enum { incSize = 4096 };
95    
96     void *buf = realloc(m_buffer, m_size + incSize);
97     if ( !buf )
98     {
99     // don't read any more, we don't have enough memory to do it
100     m_stream = NULL;
101     }
102     else // got memory for the buffer
103     {
104     m_buffer = buf;
105     m_stream->Read((char *)m_buffer + m_size, incSize);
106     m_size += m_stream->LastRead();
107     }
108     }
109     }
110    
111     inline
112     wxStreamTempInputBuffer::~wxStreamTempInputBuffer()
113     {
114     if ( m_buffer )
115     {
116     m_stream->Ungetch(m_buffer, m_size);
117     free(m_buffer);
118     }
119     }
120    
121     #endif // _WX_WXEXEC_CPP_
122    

  ViewVC Help
Powered by ViewVC 1.1.22