This file is indexed.

/usr/share/doc/libbobcat4-dev/man/sharedcondition.3.html is in libbobcat-dev 4.08.02-2build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
<!DOCTYPE html><html><head>
<meta charset="UTF-8">
<title>FBB::SharedCondition(3bobcat)</title>
<style type="text/css">
    figure {text-align: center;}
    img {vertical-align: center;}
    .XXfc {margin-left:auto;margin-right:auto;}
    .XXtc {text-align: center;}
    .XXtl {text-align: left;}
    .XXtr {text-align: right;}
    .XXvt {vertical-align: top;}
    .XXvb {vertical-align: bottom;}
</style>
<link rev="made" href="mailto:Frank B. Brokken: f.b.brokken@rug.nl">
</head>
<body text="#27408B" bgcolor="#FFFAF0">
<hr/>
<h1 id="title">FBB::SharedCondition(3bobcat)</h1>
<h2 id="author">Shared Memory Cond. Var.<br/>(libbobcat-dev_4.08.02-x.tar.gz)</h2>
<h2 id="date">2005-2017</h2>


<p>
<h2 >NAME</h2>FBB::SharedCondition - Shared Memory Condition Variable
<p>
<h2 >SYNOPSIS</h2>
    <strong >#include &lt;bobcat/sharedcondition&gt;</strong><br/>
    Linking option: <em >-lpthread, -lbobcat </em> 
<p>
<h2 >DESCRIPTION</h2>
<p>
Condition variables are used to synchronize threads based on the values of
data. Condition variables allow threads to wait until a certain condition has
occurred, after which the threads continue their actions. Thus waiting threads
don't continuously have to poll the state of a variable (requiring the threads
to gain access to the variable before they can inspect its value). Using
condition variables waiting threads simply wait until they are notified.
<p>
<strong >SharedCondition</strong> objects can be used in combination with shared
memory. <strong >SharedCondition</strong> objects interface to objects (called <em >Condition</em>
objects in this man-page) which are defined in shared memory and contain a
<em >SharedMutex</em> and a shared condition object. These <em >Condition</em> objects may
be accessed by threads running in different processes. These different
processes might run a single <em >main</em> thread, or they themselves can be
multi-threaded.
<p>
Condition variables are used in situations like these:
    <ul>
    <li> There exists a thread which should be suspended until a certain
        condition has been met. 
    <li> This thread locks a mutex (or waits until the lock has been obtained)
    <li> While the condition hasn't been met, the thread is suspended (i.e.,
        waits), automatically releasing the mutex's lock. 
    <li> Somehow (see below) the thread is resumed, at which point the thread
        has automatically reacquired the lock.
    <li> Once the condition has been met, the while loop ends, and the mutex's
        lock is released.
    <li> There exists a second thread, which influences the variables that are
        elements of the condition, and which may notify the waiting thread,
        once the required condition has been met.
    <li> This second thread locks the same mutex as used by the first thread.
    <li> The second thread modifies the variables that are involved, and if
        the required condition has been met, it notifies the first thread.
    <li> The second thread releases the mutex's lock, allowing the first
        thread to obtain the mutex's lock. 
    </ul>
<p>
While the first thread is waiting, it is suspended. It may be resumed when it
receives a notification from another thread, but also for spurious
reasons. Therefore the first thread must verify that the condition has been
met after resuming its actions.
<p>
As condition variables are always used in combination with a mutex,
<strong >SharedMutex</strong> encapsulates the mutex-handling. The software using
<strong >SharedCondition</strong> objects doesn't have to handle the mutex itself.
<p>
<strong >SharedCondition</strong> objects are used to synchronize actions by different
processes, using shared memory as their vehicle of
synchronization/communication. The actual condition variable that is used by a
<strong >SharedCondition</strong> object is defined in shared memory.  <strong >SharedCondition</strong>
objects themselves are small objects, containing the necessary information to
access the actual shared memory condition variable.
<p>
<h2 >NAMESPACE</h2>
    <strong >FBB</strong><br/>
    All constructors, members, operators and manipulators, mentioned in this
man-page, are defined in the namespace <strong >FBB</strong>.
<p>
<h2 >INHERITS FROM</h2>
    <strong >SharedMutex</strong>(3bobcat)
<p>
<h2 >CONSTRUCTORS, DESTRUCTOR</h2>
    <ul>
    <li> <strong >SharedCondition()</strong>:<br/>
       The default constructor creates an empty stub which cannot yet be used
        (or an <em >FBB::Exception</em> is thrown). As the <strong >SharedCondition</strong> class
        supports assignment operators, empty stubs can easily be
        (re)configured at any time after their construction.
<p>
<li> <strong >~SharedCondition()</strong>:<br/>
       The class's destructor releases (if applicable) its lock on the shared
        condition variables mutex lock. The destructor takes no action if its
        object is an empty stub.
    </ul>
       (Default) copy and move constructors are available. 
<p>
<h2 >OVERLOADED OPERATORS</h2>
<p>
The (default) overloaded move and copy assignment operators are available.
<p>
<h2 >MEMBER FUNCTIONS</h2>
<p>
Returning from <strong >SharedCondition</strong> member functions the offset of the
<em >SharedMemory</em> object in which the condition variable has been defined has
not changed. Internally, the current offset is saved; the requested function
is performed; and the original offset is restored. Consequently,
<strong >SharedCondition</strong> member functions can be used disregarding the
<em >SharedMemory</em>'s current offset.
<p>
<ul>
    <li> <strong >void lock() const</strong>:<br/>
       When returning from this member, the current process has locked the
        <strong >SharedCondition</strong> object. Be careful not to call <em >lock</em> twice
        during the same thread of execution (cf. <strong >sharedmutex</strong>(3bobcat) for
        details).
<p>
<li> <strong >void notify() noexept</strong>:<br/>
       One of the threads waiting on the <strong >SharedCondition</strong> object wakes
        up. The thread calling <em >notify</em> should release its mutex lock
        shortly after calling <em >notify</em>, allowing the notified thread to
        obtain the lock. A prototypical piece of pseudo code illustrating
        the use of <em >notify</em> looks like this:
       <pre>

    sharedCondition.lock();     // lock the mutex
    ...                         // operate on the condition's variables
    if (conditionWasMet)        // ready to notify
        sharedCondition.notify(); 
    sharedCondition.unlock();   // release the lock
       
</pre>

       As the <em >sharedCondition.lock ... sharedCondition.unlock</em> sequence
        itself may be executed at different flow of control sections, the
        <em >unlock</em> member cannot be called from within <em >notify</em>.
<p>
<li> <strong >void notifyAll() noexept</strong>:<br/>
       Different from the plain <em >notify</em> member, this member wakes up all of
        the threads waiting on the <strong >SharedCondition</strong> object. However, after
        the current thread has released its mutex lock only one of these
        signaled threads will actually obtain the lock. The pseudo code for
        using <em >notifyAll</em> is identical to the pseudo code for using
        <em >notify</em> (i.e., calling <em >notifyAll</em>, of course).
<p>
<li> <strong >std::streamsize offset() const</strong>:<br/>
       The location of the shared condition variable (within the
        <em >SharedMemory</em> object) is returned. The shared condition object ends
        at <em >offset() + SharedCondition::width()</em>, see below.
<p>
<li> <strong >void unlock() const</strong>:<br/>
       The object's lock is released (nothing happens if called when the
        current object does not have the object's  lock).
<p>
<li> <strong >void wait()</strong>:<br/>
       Before calling <em >wait</em> the current thread should have obtained a lock
        on the <strong >SharedCondition</strong> object. 
<p>
When calling <em >wait</em> the running thread suspends its activities and
        waits until being notified. Once notified, it reacquires the lock and
        continues. Shortly after this the process should again release its
        lock on the <strong >SharedCondition</strong> object.  lock. A prototypical piece of
        pseudo code illustrating how to use <em >wait</em> looks like this:
       <pre>

    sharedCondition.lock();         // lock the mutex
    while (conditionWasNotYetMet)   // waiting required
        sharedCondition.wait(); 
    ...                             // do something: we have the lock
    sharedCondition.unlock();       // release the lock
       
</pre>

<p>
<li> <strong >void wait(Predicate pred)</strong>:<br/>
       This member was implemented as a member template. <em >Predicate</em> either
        is a predicate function or a predicate function object. The predicate
        function or the predicate function object's function call operators
        may not require arguments. As long as <em >pred</em> is returning false,
        <em >wait()</em> (no arguments) is called. The function returns once
        <em >pred</em> has returned <em >true</em>.
<p>
The running thread should have obtained a lock on the
        <strong >SharedCondition</strong> condition variable prior to calling this member,
        and should release the lock after this member has returned.
<p>
The pseudo code for using <em >wait(pred)</em> is identical to the pseudo
        code for using <em >wait</em> (albeit that <em >pred</em> has to be passed to
        <em >wait</em>, of course).
<p>
<li> <strong >std::cv_status wait_for(std::chrono::duration&lt;Type, Unit&gt; 
        const &amp;relTime)</strong>:<br/>
       This member was implemented as a member template. <em >Type</em> defines the
        type of the variable holding the amount of time (usually <em >int64_t</em>),
        specified in time unit <em >Unit</em>. Predefined <em >duration</em> types are
        available from the <em >std::chrono</em> namespace, like
        <em >std::chrono::seconds(4)</em>, representing 4 seconds, or
        <em >std::chrono::milliseconds(30)</em>, representing 30 milliseconds.
<p>
The running thread should have obtained a lock on <strong >SharedCondition</strong>
        prior to calling this member, and should release the lock after this
        member has returned.
<p>
This member acts like <em >wait</em>, returning
        <em >std::cv_status::no_timeout</em> if a notification was received before
        <em >relTime</em> has passed. Otherwise <em >std::cv_status::timeout</em> is
        returned.
<p>
A prototypical piece of pseudo code illustrating how to use
        <em >wait_for</em> looks like this:
       <pre>

    sharedCondition.lock();         // lock the mutex
    while (conditionWasNotYetMet)   // waiting required
    {
        while (sharedCondition.wait_for(someTime) 
               == std::cv_status::timeout)
            handle_timeout 

        do_something
    }
    sharedCondition.unlock();       // release the lock
       
</pre>

       When returning from <em >wait_for</em> the current thread has obtained the
        shared condition's lock, but maybe due to a timeout: this can be
        verified by inspecting <em >wait_for's</em> return value, and an appropriate
        action can be selected.
<p>
<li> <strong >bool wait_for(std::chrono::duration&lt;Type, Unit&gt; 
        const &amp;relTime, Predicate pred)</strong>:<br/>
       This member was implemented as a member template. <em >Type</em> defines the
        type of the variable holding the amount of time (usually <em >int64_t</em>),
        specified in time unit <em >Unit</em>. <em >Predicate</em> either is a predicate
        function or a predicate function object.  The predicate function or
        the predicate function object's function call operators may not
        require arguments. 
<p>
The running thread should have obtained a lock on <strong >SharedCondition</strong>
        prior to calling this member, and should release the lock after this
        member has returned.
<p>
As long as <em >pred</em> returns false, <em >wait_for(relTime)</em> is called. If
        the latter function returns <em >std::cv_status::timeout</em>, then
        <em >pred</em> is called, and its return value is returned. Otherwise
        <em >true</em> is returned.
<p>
The pseudo code for using this member is identical to the pseudo code
        for using the abovementioned <em >wait_for</em> member (albeit that <em >pred</em>
        must also be passed to <em >wait_for</em>, of course).
<p>
<li> <strong >std::cv_status wait_until(std::chrono::time_point&lt;Clock, Duration&gt; 
        const &amp;absTime)</strong>:<br/>
       This member has been implemented as a member template. <em >Clock</em>
        defines the clock-type to use (usually <em >std::chrono::system_clock</em>),
        <em >Duration</em> is the type name of a duration type (as used with
        <em >wait_for</em>). E.g., to specify 5 seconds after the current time this
        member could be called like this:
       <pre>

    std::chrono::system_clock::now() + std::chrono::seconds(5)
        
</pre>

<p>
The running thread should have obtained a lock on <strong >SharedCondition</strong>
        prior to calling this member, and should release the lock after this
        member has returned.
<p>
This member acts like <em >wait_for(relative-time)</em>, returning
        <em >std::cv_status::no_timeout</em> if a notification was received before
        <em >absTime</em> has passed. Otherwise <em >std::cv_status::timeout</em> is
        returned.
<p>
The pseudo code for using this member is identical to the pseudo code
        for using the abovementioned <em >wait_for(relative-time)</em> member
        (albeit that absolute time must be specified).
<p>
<li> <strong >bool wait_until(std::chrono::time_point&lt;Clock, Duration&gt; 
        const &amp;absTime, Predicate pred)</strong>:<br/>
       This member was implemented as a member template. <em >Clock</em> and
        <em >Duration</em> define identical types as mentioned at the previous
        member.  <em >Predicate</em> either is a predicate function or a predicate
        function object (not expecting arguments).
<p>
The running thread should have obtained a lock on <strong >SharedCondition</strong>
        prior to calling this member, and should release the lock after this
        member has returned.
<p>
As long as <em >pred</em> returns false, <em >wait_until(absTime)</em>
        is called. If the latter function returns <em >std::cv_status::timeout</em>,
        then <em >pred</em> is called, and its return value is returned. Otherwise
        <em >true</em> is returned.
<p>
The pseudo code for using this member is identical to the pseudo code
        for using the abovementioned <em >wait_until</em> member (albeit that
        <em >pred</em> must also be passed to <em >wait_until</em>, of course).
    </ul>
<p>
<h2 >STATIC MEMBER FUNCTIONS</h2>
<p>
<ul>
    <li> <strong >SharedCondition &amp;attach(SharedMemory &amp;shmem,
                        std::ios::off_type offset = 0,
                        std::ios::seekdir origin = std::ios::beg)</strong>:<br/>
       The <em >SharedCondition</em> object interfacing to the shared condition
        variable located at <em >offset</em> (relative to <em >origin</em>) in <em >shmem</em>
        is returned. 
<p>
An <em >FBB::Exception</em> is thrown if the requested offset is invalid
        (i.e., smaller than 0 or exceeding <em >shmem.maxOffset()</em>).
<p>
<li> <strong >FBB::SharedCondition create(SharedMemory &amp;shmem)</strong>:<br/> 
       A shared condition variable is initialized at the current offset of
        the <em >SharedMemory</em> object referred to by <em >shmem</em>, or at the first
        offset of the next physical shared data segment. 
<p>
A <strong >SharedCondition</strong> object interfacing to the initialized shared
        condition variable is returned.
<p>
An <em >FBB::Exception</em> is thrown if there isn't enough memory available
        in the <em >SharedMemory</em> object to define a shared condition variable.
<p>
<li> <strong >size_t size() const</strong>:<br/>
       Returns the size in bytes of the shared condition variables stored in
        <em >SharedMemory</em> objects.
    </ul>
<p>
<h2 >EXAMPLE</h2>
<p>
<pre >
#include &lt;iostream&gt;

#include &lt;bobcat/sharedcondition&gt;
#include &lt;bobcat/sharedmemory&gt;

using namespace std;
using namespace FBB;

int main(int argc, char **argv)
try
{
    if (argc == 1)
    {
        cout &lt;&lt; 
            "Argument:\n"
            "   c: create a shared memory segment + SharedCondition "
                                                    ", display ID\n" 
            "   k &lt;id&gt;: kill shared memory segment &lt;id&gt;\n"
            "   m &lt;id&gt;: show a message every 5 secs, otherwise wait until\n"
            "           being notified in segment &lt;id&gt;\n"
            "   n &lt;id&gt;: notify the SharedCondition in segment ID &lt;id&gt;\n"
        ;
        return 0;
    }

    switch (argv[1][0])
    {
        case 'c':
        {
            SharedMemory shmem(1, SharedMemory::kB);

            SharedCondition cond = SharedCondition::create(shmem);   

            void *ptr = shmem.ptr();

            cout &lt;&lt; "ID = " &lt;&lt; shmem.id() &lt;&lt; ", SharedCondition at " &lt;&lt; 
                    cond.offset() &lt;&lt; endl;
            break;
        }

        case 'k':
        {
            SharedMemory shmem(stoll(argv[2]));
            shmem.kill();
            break;
        }

        case 'm':
        {
            SharedMemory shmem(stoll(argv[2]));
            SharedCondition cond = SharedCondition::attach(shmem);

            cond.lock();
            cout &lt;&lt; "Obtained the lock. Now waiting for a notification\n";
        
            while (true)
            {
                switch (cond.wait_for(chrono::seconds(5)))
                {
                    case cv_status::timeout:
                        cout &lt;&lt; "Waited for 5 seconds\n\n";
                    break;

                    case cv_status::no_timeout:
                        cond.unlock();
                        cout &lt;&lt; "Received the notification. Unlocked.\n";
                    return 0;
                }
            }
        }
            
        case 'w':
        {
            SharedMemory shmem(stoll(argv[2]));
            SharedCondition cond = SharedCondition::attach(shmem);

            cond.lock();
            cout &lt;&lt; "Obtained the lock. Now waiting for a notification\n";
        
            cond.wait();
            cout &lt;&lt; "Received the notification. Unlocking.\n";

            cond.unlock();
            break;
        }
            
        case 'n':
        {
            SharedMemory shmem(stoll(argv[2]));

            SharedCondition cond = SharedCondition::attach(shmem);

            cout &lt;&lt; "Notifying the other after Enter ";
            cin.ignore(1000, '\n');

            cond.lock();
            cout &lt;&lt; "Obtained the lock. Now notifying the other\n";
            cond.notify();
            cout &lt;&lt; "Sent the notification. Now unlocking.\n";
            cond.unlock();
            break;
        }

    }
}
catch (exception const &amp;exc)
{
    cout &lt;&lt; "Exception: " &lt;&lt; exc.what() &lt;&lt; endl;
}

</pre>

<p>
<h2 >FILES</h2>
    <em >bobcat/sharedcondition</em> - defines the class interface
<p>
<h2 >SEE ALSO</h2>
    <strong >bobcat</strong>(7)
        <strong >isharedstream</strong>(3bobcat),
        <strong >osharedstream</strong>(3bobcat),
        <strong >sharedblock</strong>(3bobcat), 
        <strong >sharedmemory</strong>(3bobcat),
        <strong >sharedpos</strong>(3bobcat), 
        <strong >sharedreadme</strong>(7bobcat), 
        <strong >sharedsegment</strong>(3bobcat), 
        <strong >sharedstream</strong>(3bobcat), 
        <strong >sharedstreambuf</strong>(3bobcat)
<p>
<h2 >BUGS</h2>
    None Reported.
<p>

<h2 >DISTRIBUTION FILES</h2>
    <ul>
    <li> <em >bobcat_4.08.02-x.dsc</em>: detached signature;
    <li> <em >bobcat_4.08.02-x.tar.gz</em>: source archive;
    <li> <em >bobcat_4.08.02-x_i386.changes</em>: change log;
    <li> <em >libbobcat1_4.08.02-x_*.deb</em>: debian package holding the
            libraries;
    <li> <em >libbobcat1-dev_4.08.02-x_*.deb</em>: debian package holding the
            libraries, headers and manual pages;
    <li> <em >http://sourceforge.net/projects/bobcat</em>: public archive location;
    </ul>
<p>
<h2 >BOBCAT</h2>
    Bobcat is an acronym of `Brokken's Own Base Classes And Templates'.
<p>
<h2 >COPYRIGHT</h2>
    This is free software, distributed under the terms of the 
    GNU General Public License (GPL).
<p>
<h2 >AUTHOR</h2>
    Frank B. Brokken (<strong >f.b.brokken@rug.nl</strong>).
<p>
</body>
</html>