1// $Header$
2//
3// Copyright (C) 2002 - 2004, by
4//
5// Carlo Wood, Run on IRC <carlo@alinoe.com>
6// RSA-1024 0x624ACAD5 1997-01-26                    Sign & Encrypt
7// Fingerprint16 = 32 EC A7 B6 AC DB 65 A6  F6 F6 55 DD 1C DC FF 61
8//
9// This file may be distributed under the terms of the Q Public License
10// version 1.0 as appearing in the file LICENSE.QPL included in the
11// packaging of this file.
12//
13
14#ifndef LIBCWD_SET_OSTREAM_INL
15#define LIBCWD_SET_OSTREAM_INL
16
17#ifndef LIBCWD_PRIVATE_LOCK_INTERFACE_H
18#include <libcwd/private_lock_interface.h>
19#endif
20#ifndef LIBCWD_PRIVATE_THREADING_H
21#include <libcwd/private_threading.h>
22#endif
23
24#if LIBCWD_THREAD_SAFE || defined(LIBCWD_DOXYGEN)
25namespace libcwd {
26
27/**
28 * \brief Set output device and provide external lock.
29 * \ingroup group_destination
30 *
31 * Assign a new \c ostream to this %debug object.&nbsp;
32 * The \c ostream will only be written to after obtaining the lock
33 * that is passed as second argument.  Each \c ostream needs to have
34 * a unique lock.&nbsp; If the application also writes directly
35 * to the same \c ostream then use the same lock.
36 *
37 * <b>Example:</b>
38 *
39 * \code
40 * MyLock lock;
41 *
42 * // Uses MyLock::lock(), MyLock::trylock() and MyLock::unlock().
43 * Debug( libcw_do.set_ostream(&std::cerr, &lock) );
44 *
45 * lock.lock();
46 * std::cerr << "The application uses cerr too\n";
47 * lock.unlock();
48 * \endcode
49 */
50template<class T>
51  void debug_ct::set_ostream(std::ostream* os, T* mutex)
52  {
53    _private_::lock_interface_base_ct* new_mutex = new _private_::lock_interface_tct<T>(mutex);
54#if CWDEBUG_DEBUGT
55    LIBCWD_TSD_DECLARATION;
56#endif
57    LIBCWD_DEFER_CANCEL;
58    _private_::mutex_tct<_private_::set_ostream_instance>::lock();
59    _private_::lock_interface_base_ct* old_mutex = M_mutex;
60    if (old_mutex)
61      old_mutex->lock();		// Make sure all other threads left this critical area.
62    M_mutex = new_mutex;
63    if (old_mutex)
64    {
65      old_mutex->unlock();
66      delete old_mutex;
67    }
68    private_set_ostream(os);
69    _private_::mutex_tct<_private_::set_ostream_instance>::unlock();
70    LIBCWD_RESTORE_CANCEL;
71  }
72
73}  // namespace libcwd
74
75#endif // LIBCWD_THREAD_SAFE
76#endif // LIBCWD_SET_OSTREAM_INL
77
78