/****************************************************************************
**
** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved.
**
** This file is part of the documentation of the Qt Toolkit.
**
** This file may be used under the terms of the GNU General Public
** License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file.  Alternatively you may (at
** your option) use any later version of the GNU General Public
** License if such license has been publicly approved by Trolltech ASA
** (or its successors, if any) and the KDE Free Qt Foundation. In
** addition, as a special exception, Trolltech gives you certain
** additional rights. These rights are described in the Trolltech GPL
** Exception version 1.2, which can be found at
** http://www.trolltech.com/products/qt/gplexception/ and in the file
** GPL_EXCEPTION.txt in this package.
**
** Please review the following information to ensure GNU General
** Public Licensing requirements will be met:
** http://trolltech.com/products/qt/licenses/licensing/opensource/. If
** you are unsure which license is appropriate for your use, please
** review the following information:
** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
** or contact the sales department at sales@trolltech.com.
**
** In addition, as a special exception, Trolltech, as the sole
** copyright holder for Qt Designer, grants users of the Qt/Eclipse
** Integration plug-in the right for the Qt/Eclipse Integration to
** link to functionality provided by Qt Designer and its related
** libraries.
**
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly
** granted herein.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/

/*!
  \example ipc/sharedmemory
  \title Shared Memory Example

  The Shared Memory example shows how to use the QSharedMemory class
  to implement inter-process communication using shared memory. To
  build the example, run make. To run the example, start two instances
  of the executable. The main() function creates an \l {QApplication}
  {application} and an instance of our example's Dialog class. The
  dialog is displayed and then control is passed to the application in
  the standard way.

  \snippet examples/ipc/sharedmemory/main.cpp 0

  Two instances of class Dialog appear.

  \image sharedmemory-example_1.png Screenshot of the Shared Memory example

  Class Dialog inherits QDialog. It encapsulates the user interface
  and an instance of QSharedMemory. It also has two public slots,
  loadFromFile() and loadFromMemory() that correspond to the two
  buttons on the dialog.

  \snippet examples/ipc/sharedmemory/dialog.h 0

  The constructor builds the user interface widgets and connects the
  clicked() signal of each button to the corresponding slot function.

  \snippet examples/ipc/sharedmemory/dialog.cpp 0

  Note that "QSharedMemoryExample" is passed to the \l {QSharedMemory}
  {QSharedMemory()} constructor to be used as the key. This will be
  used by the system as the identifier of the underlying shared memory
  segment.

  Click the \tt {Load Image From File...} button on one of the
  dialogs. The loadFromFile() slot is invoked. First, it tests whether
  a shared memory segment is already attached to the process. If so,
  that segment is detached from the process, so we can be assured of
  starting off the example correctly.

  \snippet examples/ipc/sharedmemory/dialog.cpp 1

  The user is then asked to select an image file using
  QFileDialog::getOpenFileName(). The selected file is loaded into a
  QImage. Using a QImage lets us ensure that the selected file is a
  valid image, and it also allows us to immediately display the image
  in the dialog using setPixmap().

  Next the image is streamed into a QBuffer using a QDataStream. This
  gives us the size, which we then use to \l {QSharedMemory::}
  {create()} our shared memory segment. Creating a shared memory
  segment automatically \l {QSharedMemory::attach()} {attaches} the
  segment to the process. Using a QBuffer here lets us get a pointer
  to the image data, which we then use to do a memcopy() from the
  QBuffer into the shared memory segment.

  \snippet examples/ipc/sharedmemory/dialog.cpp 2

  Note that we \l {QSharedMemory::} {lock()} the shared memory segment
  before we copy into it, and we \l {QSharedMemory::} {unlock()} it
  again immediately after the copy. This ensures we have exclusive
  access to the shared memory segment to do our memcopy(). If some
  other process has the segment lock, then our process will block
  until the lock becomes available.

  Note also that the function does not \l {QSharedMemory::} {detach()}
  from the shared memory segment after the memcopy() and
  unlock(). Recall that when the last process detaches from a shared
  memory segment, the segment is released by the operating
  system. Since this process only one that is attached to the shared
  memory segment at the moment, if loadFromFile() detached from the
  shared memory segment, the segment would be destroyed before we get
  to the next step.

  When the function returns, if the file you selected was qt.png, your
  first dialog looks like this.

  \image sharedmemory-example_2.png Screenshot of the Shared Memory example

  In the second dialog, click the \tt {Display Image From Shared
  Memory} button. The loadFromMemory() slot is invoked. It first \l
  {QSharedMemory::attach()} {attaches} the process to the same shared
  memory segment created by the first process. Then it \l
  {QSharedMemory::lock()} {locks} the segment for exclusive access and
  links a QBuffer to the image data in the shared memory segment. It
  then streams the data into a QImage and \l {QSharedMemory::unlock()}
  {unlocks} the segment.

  \snippet examples/ipc/sharedmemory/dialog.cpp 3

  In this case, the function does \l {QSharedMemory::} {detach()} from
  the segment, because now we are effectively finished using
  it. Finally, the QImage is displayed. At this point, both dialogs
  should be showing the same image. When you close the first dialog,
  the Dialog destructor calls the QSharedMemory destructor, which
  detaches from the shared memory segment. Since this is the last
  process to be detached from the segment, the operating system will
  now release the shared memory.

 */
