1. New classes documented: wxCriticalSection, wxMutexLocker,

wxCriticalSectionLocker
2. New overviews: Threads overview, Container classes overview
3. A modest update of wxList/wxNode docs to bring them up to date
   with the new classes (array.tex is simply empty for the moment)


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1311 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 1999-01-02 23:02:30 +00:00
parent 839dda6f70
commit 6e6110ee81
15 changed files with 367 additions and 51 deletions

3
docs/latex/wx/array.tex Normal file
View File

@ -0,0 +1,3 @@
\section{\class{wxArray}}\label{wxarray}
TODO

View File

@ -30,6 +30,7 @@ $$\image{14cm;0cm}{wxclass.ps}$$
\input accel.tex
\input activevt.tex
\input app.tex
\input array.tex
\input autoobj.tex
\input button.tex
\input bitmap.tex
@ -52,6 +53,8 @@ $$\image{14cm;0cm}{wxclass.ps}$$
\input conditn.tex
\input config.tex
\input control.tex
\input critsect.tex
\input crtslock.tex
\input cursor.tex
\input database.tex
\input date.tex
@ -118,6 +121,7 @@ $$\image{14cm;0cm}{wxclass.ps}$$
\input moveevt.tex
\input mltchdlg.tex
\input mutex.tex
\input mutexlck.tex
\input node.tex
\input notebook.tex
\input noteevt.tex

View File

@ -0,0 +1,49 @@
\section{\class{wxCriticalSection}}\label{wxcriticalsection}
A critical section object is used exactly for the same purpose as
\helpref{mutexes}{wxMutex}. The only difference is that under Windows platform
critical sections are only visible inside one process, while mutexes may be
shared between processes, so using critical sections is slightly more
efficient. The terminology is also slightly different: mutex may be locked (or
acquired) and unlocked (or released) while critical section is entered and left
by the program.
Finally, you should try to use
\helpref{wxCriticalSectionLocker}{wxcriticalsectionlocker} class whenever
possible instead of directly using wxCriticalSection for the same reasons
\helpref{wxMutexLocker}{wxmutexlocker} is preferrable to
\helpref{wxMutex}{wxmutex} - please see wxMutex for an example.
\wxheading{Derived from}
None.
\wxheading{See also}
\helpref{wxThread}{wxthread}, \helpref{wxCondition}{wxcondition},
\helpref{wxMutexLocker}{wxmutexlocker}, \helpref{wxCriticalSection}{wxcriticalsection}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxCriticalSection::wxCriticalSection}\label{wxcriticalsectionctor}
\func{}{wxCriticalSection}{\void}
Default constructor initializes critical section object.
\membersection{wxCriticalSection::\destruct{wxCriticalSection}}\label{wxcriticalsectiondtor}
\func{}{\destruct{wxCriticalSection}}{\void}
Destructor frees the ressources.
\membersection{wxCriticalSection::Enter}\label{wxcriticalsectionenter}
\func{void }{Enter}{\void}
Enter the critical section (same as locking a mutex). There is no error return
for this function. After entering the critical section protecting some global
data the thread running in critical section may safely use/modify it.
\membersection{wxCriticalSection::Leave}\label{wxcriticalsectionleave}
\func{void }{Leave}{\void}
Leave the critical section allowing other threads use the global data protected
by it. There is no error return for this function.

View File

@ -0,0 +1,29 @@
\section{\class{wxCriticalSectionLocker}}\label{wxcriticalsectionlocker}
This is a small helper class to be used with \helpref{wxCriticalSection}{wxcriticalsection}
objects. A wxCriticalSectionLocker enters the critical section in the
constructor and leaves it in the destructor making it much more difficult to
forget to leave a critical section (which, in general, will lead to serious
and difficult to debug problems).
\wxheading{Derived from}
None.
\wxheading{See also}
\helpref{wxCriticalSection}{wxcriticalsection},
\helpref{wxMutexLocker}{wxmutexlocker}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxCriticalSectionLocker::wxCriticalSectionLocker}\label{wxcriticalsectionlockerctor}
\func{}{wxCriticalSectionLocker}{\param{wxCriticalSection *}{criticalsection}}
Constructs a wxCriticalSectionLocker object associated with given
criticalsection which must be non NULL and enters it.
\membersection{wxCriticalSectionLocker::\destruct{wxCriticalSectionLocker}}\label{wxcriticalsectionlockerdtor}
\func{}{\destruct{wxCriticalSectionLocker}}{\void}
Destuctor leaves the criticalsection.

View File

@ -1,14 +1,79 @@
\section{\class{wxList}}\label{wxlist}
This class provides linked list functionality for wxWindows, and for an application
if it wishes. Depending on the form of constructor used, a list can be keyed on
integer or string keys to provide a primitive look-up ability. See \helpref{wxHashTable}{wxhashtable}\rtfsp
for a faster method of storage when random access is required.
wxList classes provide linked list functionality for wxWindows, and for an
application if it wishes. Depending on the form of constructor used, a list
can be keyed on integer or string keys to provide a primitive look-up ability.
See \helpref{wxHashTable}{wxhashtable}\rtfsp for a faster method of storage
when random access is required.
While wxList class in the previous versions of wxWindows only could contain
elements of type wxObject and had essentially untyped interface (thus allowing
you to put apples in the list and read back oranges from it), the new wxList
classes family may contain elements of any type and has much more stricter type
checking. Unfortunately, it also requires an additional line to be inserted in
your program for each list class you use (which is the only solution short of
using templates which is not done in wxWindows because of portability issues).
The general idea is to have the base class wxListBase working with {\it void *}
data but make all of its dangerous (because untyped) functions protected, so
that they can only be used from derived classes which, in turn, expose a type
safe interface. With this approach a new wxList-like class must be defined for
each list type (i.e. list of ints, of wxStrings or of MyObjects). This is done
with {\it WX\_DECLARE\_LIST} and {\it WX\_IMPLEMENT\_LIST} macros like this
(notice the similarity with WX\_DECLARE\_OBJARRAY and WX\_IMPLEMENT\_OBJARRAY
macros):
\wxheading{Example}
{\small%
\begin{verbatim}
// this part might be in a header or source (.cpp) file
class MyListElement
{
... // whatever
};
// declare our list class: this macro declares and partly implements MyList
// class (which derives from wxListBase)
WX_DECLARE_LIST(MyListElement, MyList)
...
// the only requirment for the rest is to be AFTER the full declaration of
// MyListElement (for WX_DECLARE_LIST forward declaration is enough), but
// usually it will be found in the source file and not in the header
#include <wx/listimpl.cpp>
WX_DEFINE_LIST(MyList)
// now MyList class may be used as a usual wxList, but all of its methods
// will take/return the objects of the right (i.e. MyListElement) type. You
// also have MyList::Node type which is the type-safe version of wxNode.
MyList list;
MyListElement element;
list.Add(element); // ok
list.Add(17); // error: incorrect type
// let's iterate over the list
for ( MyList::Node *node = list.GetFirst(); node; node = node->GetNext() )
{
MyListElement *current = node->GetData();
...process the current element...
}
\end{verbatim}
}
For compatibility with previous versions wxList and wxStringList classes are
still defined, but their usage is deprecated and they will disappear in the
future versions completely.
\wxheading{Derived from}
\helpref{wxObject}{wxobject}
{\bf WARNING: } the rest of documentation may be out-of-date.
\wxheading{Example}
It is very common to iterate on a list as follows:
@ -60,11 +125,11 @@ types (such as char*) may be used with appropriate casting.
\wxheading{See also}
\helpref{wxNode}{wxnode}, \helpref{wxStringList}{wxstringlist}
\helpref{wxNode}{wxnode}, \helpref{wxStringList}{wxstringlist},
\helpref{wxArray}{wxarray}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxList::wxList}
\func{}{wxList}{\void}

View File

@ -1,7 +1,61 @@
\section{\class{wxMutex}}\label{wxmutex}
A wxMutex controls mutual exclusion, to prevent two or more threads accessing
the same piece of code.
A mutex object is a synchronization object whose state is set to signaled when
it is not owned by any thread, and nonsignaled when it is owned. Its name comes
from its usefulness in coordinating mutually-exclusive access to a shared
resource. Only one thread at a time can own a mutex object.
For example, when several thread use the data stored in the linked list,
modifications to the list should be only allowed to one thread at a time
because during a new node addition the list integrity is temporarily broken
(this is also called {\it program invariant}).
\wxheading{Example}
{\small%
\begin{verbatim}
// this variable has an "s_" prefix because it is static: seeing an "s_" in
// a multithreaded program is in general a good sign that you should use a
// mutex (or a critical section)
static wxMutex *s_mutexProtectingTheGlobalData;
// we store some numbers in this global array which is presumably used by
// several threads simultaneously
wxArrayInt s_data;
void MyThread::AddNewNode(int num)
{
// ensure that no other thread accesses the list
s_mutexProtectingTheGlobalList->Lock();
s_data.Add(num);
s_mutexProtectingTheGlobalList->Unlock();
}
// return TRUE the given number is greater than all array elements
bool MyThread::IsGreater(int num)
{
// before using the list we must acquire the mutex
wxMutexLocker lock(s_mutexProtectingTheGlobalData);
size_t count = s_data.Count();
for ( size_t n = 0; n < count; n++ )
{
if ( s_data[n] > num )
return FALSE;
}
return TRUE;
}
\end{verbatim}
}
Notice how wxMutexLocker was used in the second function to ensure that the
mutex is unlocked in any case: whether the function returns TRUE or FALSE
(because the destructor of the local object {\it lock} is always called). Using
this class instead of directly using wxMutex is, in general safer and is even
more so if yoor program uses C++ exceptions.
\wxheading{Derived from}
@ -9,7 +63,8 @@ None.
\wxheading{See also}
\helpref{wxThread}{wxthread}, \helpref{wxCondition}{wxcondition}
\helpref{wxThread}{wxthread}, \helpref{wxCondition}{wxcondition},
\helpref{wxMutexLocker}{wxmutexlocker}, \helpref{wxCriticalSection}{wxcriticalsection}
\latexignore{\rtfignore{\wxheading{Members}}}
@ -43,9 +98,9 @@ One of:
\twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf MUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.}
\twocolitem{{\bf MUTEX\_BUSY}}{The mutex is already locked by another thread.}
\twocolitem{{\bf wxMUTEX\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf wxMUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.}
\twocolitem{{\bf wxMUTEX\_BUSY}}{The mutex is already locked by another thread.}
\end{twocollist}
\membersection{wxMutex::TryLock}\label{wxmutextrylock}
@ -60,9 +115,9 @@ One of:
\twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf MUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.}
\twocolitem{{\bf MUTEX\_BUSY}}{The mutex is already locked by another thread.}
\twocolitem{{\bf wxMUTEX\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf wxMUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.}
\twocolitem{{\bf wxMUTEX\_BUSY}}{The mutex is already locked by another thread.}
\end{twocollist}
\membersection{wxMutex::Unlock}\label{wxmutexunlock}
@ -77,10 +132,10 @@ One of:
\twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf MUTEX\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf MUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.}
\twocolitem{{\bf MUTEX\_BUSY}}{The mutex is already locked by another thread.}
\twocolitem{{\bf MUTEX\_UNLOCKED}}{The calling thread tries to unlock an unlocked mutex.}
\twocolitem{{\bf wxMUTEX\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf wxMUTEX\_DEAD\_LOCK}}{A deadlock situation was detected.}
\twocolitem{{\bf wxMUTEX\_BUSY}}{The mutex is already locked by another thread.}
\twocolitem{{\bf wxMUTEX\_UNLOCKED}}{The calling thread tries to unlock an unlocked mutex.}
\end{twocollist}

View File

@ -0,0 +1,36 @@
\section{\class{wxMutexLocker}}\label{wxmutexlocker}
This is a small helper class to be used with \helpref{wxMutex}{wxmutex}
objects. A wxMutexLocker acquires a mutex lock in the constructor and releases
(or unlocks) the mutex in the destructor making it much more difficult to
forget to release a mutex (which, in general, will promptly lead to the serious
problems). See \helpref{wxMutex}{wxmutex} for an example of wxMutexLocker
usage.
\wxheading{Derived from}
None.
\wxheading{See also}
\helpref{wxMutex}{wxmutex},
\helpref{wxCriticalSectionLocker}{wxcriticalsectionlocker}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxMutexLocker::wxMutexLocker}\label{wxmutexlockerctor}
\func{}{wxMutexLocker}{\param{wxMutex *}{mutex}}
Constructs a wxMutexLocker object associated with mutex which must be non NULL
and locks it. Call \helpref{IsOk}{wxmutexisok} to check if the mutex was
successfully locked.
\membersection{wxMutexLocker::\destruct{wxMutexLocker}}\label{wxmutexlockerdtor}
\func{}{\destruct{wxMutexLocker}}{\void}
Destuctor releases the mutex if it was successfully acquired in the ctor.
\membersection{wxMutexLocker::IsOk}\label{wxmutexlockerisok}
\constfunc{bool}{IsOk}{\void}
Returns TRUE if mutex was acquired in the constructor, FALSE otherwise.

View File

@ -1,10 +1,16 @@
\section{\class{wxNode}}\label{wxnode}
\section{\class{wxNodeBase}}\label{wxnode}
A node structure used in linked lists (see \helpref{wxList}{wxlist}).
A node structure used in linked lists (see \helpref{wxList}{wxlist}) and
derived classes. You should never use wxNodeBase class directly because it
works with untyped (void *) data and this is unsafe. Use wxNode-derived classes
which are defined by WX\_DECLARE\_LIST and WX\_DEFIBE\_LIST macros instead as
described in \helpref{wxList}{wxlist} documentation (see example there). wxNode
is defined for compatibility as wxNodeBase containing "wxObject *" pointer, but
usage of this class is deprecated.
\wxheading{Derived from}
\helpref{wxObject}{wxobject}
None.
\wxheading{See also}
@ -12,33 +18,32 @@ A node structure used in linked lists (see \helpref{wxList}{wxlist}).
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxNode::Data}
\membersection{wxNodeBase::GetData}
\func{wxObject *}{Data}{\void}
\func{void *}{Data}{\void}
Retrieves the client data pointer associated with the node. This will
have to be cast to the correct type.
Retrieves the client data pointer associated with the node.
\membersection{wxNode::Next}
\membersection{wxNodeBase::GetNext}
\func{wxNode *}{Next}{\void}
\func{wxNodeBase *}{Next}{\void}
Retrieves the next node (NULL if at end of list).
\membersection{wxNode::Previous}
\membersection{wxNodeBase::Previous}
\func{wxNode *}{Previous}{\void}
\func{wxNodeBase *}{GetPrevious}{\void}
Retrieves the previous node (NULL if at start of list).
\membersection{wxNode::SetData}
\membersection{wxNodeBase::SetData}
\func{void}{SetData}{\param{wxObject *}{data}}
\func{void}{SetData}{\param{void *}{data}}
Sets the data associated with the node (usually the pointer will have been
set when the node was created).
\membersection{wxNode::IndexOf}
\membersection{wxNodeBase::IndexOf}
\func{int}{IndexOf}{\void}

View File

@ -27,15 +27,15 @@ application.
An example of defining an application follows:
\begin{verbatim}
class DerivedApp: public wxApp
class DerivedApp : public wxApp
{
public:
bool OnInit(void);
public:
virtual bool OnInit();
};
IMPLEMENT_APP(DerivedApp)
bool DerivedApp::OnInit(void)
bool DerivedApp::OnInit()
{
wxFrame *the_frame = new wxFrame(NULL, argv[0]);
...

View File

@ -0,0 +1,59 @@
\section{Container classes overview}\label{wxcontaineroverview}
Classes: \helpref{wxList}{wxlist}, \helpref{wxArray}{wxarray}
wxWindows uses itself several container classes including (double) linked lists
and dynamic arrays (i.e. arrays which expand automatically when they become
full). For both historical and portability reasons wxWindows does not
use STL which provides the standard implementation of many container classes in
C++: first of all, wxWindows had existed well before STL was written and
secondly we don't believe that today compilers can deal really well with all of
STL classes (this is especially true for some less common platforms). Of
course, the compilers are evolving quite rapidly and hopefully their progress
will allow to base future versions of wxWindows on STL - but this is not yet
the case.
wxWindows container classes don't pretend to be as powerful or full as STL
ones, but they are quite useful and may be compiled with absolutely any C++
compiler. They're used internally by wxWindows, but may, of course, be used in
your programs as well if you wish.
The list classes in wxWindows are double-linked lists which may either own the
objects they contain (meaning that the list deletes the object when it is
removed from the list or the list itself is destroyed) or just store the
pointers depending on whether you called or not
\helpref{wxList::DeleteContents}{wxlistdeletecontents} method.
Dynamic arrays resemble to C arrays but with two important differences: they
provide run-time range checking in debug builds and they expand automatically
the allocated memory when there is no more space for new items. They come in
two sorts: the "plain" arrays which store either built-in types such as "char",
"int" or "bool" or the pointers to arbitrary objects, or "object arrays" which
own the object pointers to which they store.
For the same portability reasons, container classes implementation in wxWindows
does not use templates, but is rather based on C preprocessor i.e. is done with
the macros: {\it WX\_DECLARE\_LIST} and {\it WX\_DEFINE\_LIST} for the linked
lists and {\it WX\_DECLARE\_ARRAY}, {\it WX\_DECLARE\_OBJARRAY} and {\it
WX\_DEFINE\_OBJARRAY} for the dynamic arrays. The "DECLARE" macro declares a
new container class containing the elements of given type and is needed for all
three types of container classes: lists, arrays and objarrays. The "DEFINE"
classes must be inserted in your program in a place where the {\bf full
declaration of container element class is in scope} (i.e. not just forward
declaration), otherwise destructors of the container elements will not be
called! As array classes never delete the items they contain anyhow, there is
no WX\_DEFINE\_ARRAY macro for them.
Examples of usage of these macros may be found in \helpref{wxList}{wxlist} and
\helpref{wxArray}{wxarray} documentation.
Finally, wxWindows predefines several commonly used container classes. wxList
is defined for compatibility with previous versions as a list containing
wxObjects and wxStringList as a list of C-style strings (char *), both of these
classes are deprecated and should not be used in new programs. The following
array classes are defined: wxArrayInt, wxArrayLong, wxArrayPtrVoid and
wxArrayString. The first three store elements of corresponding types, but
wxArrayString is somewhat special: it is an optimized version of wxArray which
uses its knowledge about \helpref{wxString}{wxstring} reference counting
schema.

View File

@ -1,6 +1,13 @@
\section{\class{wxThread}}\label{wxthread}
A wxThread manages a system thread, code which executes as a mini-process within the application.
A thread is basically a path of execution through a program. Threads are also
sometimes calls {\it light-wight processes}, but the fundamental difference
between threads and processes is that memory spaces of different processes are
separated while all threads share the same address space. While it makes it
much easier to share common data between several threads, it also makes much
easier to shoot oneself in a leg, so careful use of synchronization objects
such as \helpref{mutexes}{wxmutex} and/or \helpref{critical
sections}{wxcriticalsection} is recommended.
\wxheading{Derived from}
@ -36,9 +43,9 @@ One of:
\twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf THREAD\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf THREAD\_NO\_RESOURCE}}{There were insufficient resources to create a new thread.}
\twocolitem{{\bf THREAD\_RUNNING}}{The thread is already running.}
\twocolitem{{\bf wxTHREAD\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf wxTHREAD\_NO\_RESOURCE}}{There were insufficient resources to create a new thread.}
\twocolitem{{\bf wxTHREAD\_RUNNING}}{The thread is already running.}
\end{twocollist}
\membersection{wxThread::DeferDestroy}\label{wxthreaddeferdestroy}
@ -60,8 +67,8 @@ One of:
\twocolwidtha{7cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf THREAD\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf THREAD\_NOT\_RUNNING}}{The thread is not running.}
\twocolitem{{\bf wxTHREAD\_NO\_ERROR}}{There was no error.}
\twocolitem{{\bf wxTHREAD\_NOT\_RUNNING}}{The thread is not running.}
\end{twocollist}
\membersection{wxThread::GetID}\label{wxthreadgetid}
@ -95,7 +102,7 @@ Returns TRUE if the thread is alive.
\constfunc{bool}{IsMain}{\void}
Returns TRUE if the thread is the main application thread.
Returns TRUE if the calling thread is the main application thread.
\membersection{wxThread::Join}\label{wxthreadjoin}
@ -123,9 +130,3 @@ The following priorities are already defined:
\twocolitem{{\bf WXTHREAD\_DEFAULT\_PRIORITY}}{50}
\twocolitem{{\bf WXTHREAD\_MAX\_PRIORITY}}{100}
\end{twocollist}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "referenc"
%%% End:

View File

@ -1,6 +1,7 @@
\section{Log classes overview}\label{wxlogoverview}
Classes: \helpref{wxLog}{wxlog}
%\helpref{wxLogStderr}{wxlogstderr},%
%\helpref{wxLogOstream}{wxlogostream}, \helpref{wxLogTextCtrl}{wxlogtextctrl},%
%\helpref{wxLogWindow}{wxlogwindow}, \helpref{wxLogGui}{wxloggui},%

View File

@ -5,6 +5,7 @@
This chapter contains a selection of topic overviews.
\input tapp.tex
\input tcontain.tex
\input tlog.tex
\input tconfig.tex
\input tbitmap.tex
@ -36,4 +37,5 @@ This chapter contains a selection of topic overviews.
\input tgrid.tex
\input tstring.tex
\input tdnd.tex
\input tthreads.tex
\input tusage.tex

View File

@ -0,0 +1,7 @@
\section{Multithreading overview}\label{wxthreadoverview}
Classes: \helpref{wxThread}{wxthread}, \helpref{wxMutex}{wxmutex},
\helpref{wxCriticalSection}{wxcriticalsection},
\helpref{wxCondition}{wxcondition}
TODO

View File

@ -1011,7 +1011,7 @@ Most, but not all, windows respond to this event.
\membersection{wxWindow::OnIdle}\label{wxwindowonidle}
\func{void}{Onidle}{\param{wxIdleEvent\& }{event}}
\func{void}{OnIdle}{\param{wxIdleEvent\& }{event}}
Provide this member function for any processing which needs to be done
when the application is idle.