This file is indexed.

/usr/include/ucommon/containers.h is in libucommon-dev 6.0.7-1.1.

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
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
// Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
//
// This file is part of GNU uCommon C++.
//
// GNU uCommon C++ is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU uCommon C++ is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with GNU uCommon C++.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Threadsafe object containers.  This is used to better define
 * object containers and manipulating classes which can be presumed to be
 * fully threadsafe and thread-aware.  This has to be defined separately
 * to assure correct order of preceeding headers as well as to better
 * organize the library for clarity.  Most of these classes and templates
 * work with classes derived from Object and LinkedObject and make use of
 * conditional for time constrained acquisition of managed objects.
 * @file ucommon/containers.h
 */

#ifndef _UCOMMON_CONTAINERS_H_
#define _UCOMMON_CONTAINERS_H_

#ifndef _UCOMMON_CONFIG_H_
#include <ucommon/platform.h>
#endif

#ifndef _UCOMMON_PROTOCOLS_H_
#include <ucommon/protocols.h>
#endif

#ifndef  _UCOMMON_LINKED_H_
#include <ucommon/linked.h>
#endif

#ifndef  _UCOMMON_MEMORY_H_
#include <ucommon/memory.h>
#endif

#ifndef  _UCOMMON_THREAD_H_
#include <ucommon/thread.h>
#endif

NAMESPACE_UCOMMON

/**
 * Linked allocator helper for linked_allocator template.  This is used
 * to alloc an array of typed objects tied to a free list in a single
 * operation.
 * @author David Sugar <dyfet@gnutelephony.org>
 */
class __EXPORT LinkedAllocator : private Conditional
{
protected:
    LinkedObject *freelist;

    LinkedAllocator();

    LinkedObject *get(void);

    LinkedObject *get(timeout_t timeout);

    void release(LinkedObject *node);

public:
    /**
     * Test if there is still objects in the free list.
     * @return true if there are objects.
     */
    operator bool();

    /**
     * Test if the free list is empty.
     * @return true if the free list is empty.
     */
    bool operator!();
};

/**
 * A thread-safe buffer for serializing and streaming class data.  While
 * the queue and stack operate by managing lists of reference pointers to
 * objects of various mixed kind, the buffer holds physical copies of objects
 * that being passed through it, and all must be the same size.  For this
 * reason the buffer is normally used through the bufferof<type> template
 * rather than stand-alone.  The buffer is accessed in fifo order.
 * @author David Sugar <dyfet@gnutelephony.org>
 */
class __EXPORT Buffer : protected Conditional
{
private:
    size_t bufsize, objsize;
    caddr_t buf, head, tail;
    unsigned objcount, limit;

protected:
    /**
     * Create a buffer to hold a series of objects.
     * @param size of each object in buffer.
     * @param count of objects in the buffer.
     */
    Buffer(size_t typesize, size_t count);

    /**
     * Deallocate buffer and unblock any waiting threads.
     */
    virtual ~Buffer();

    /**
     * Get the next object from the buffer.
     * @param timeout to wait when buffer is empty in milliseconds.
     * @return pointer to next object in the buffer or NULL if timed out.
     */
    void *get(timeout_t timeout);

    /**
     * Get the next object from the buffer.  This blocks until an object
     * becomes available.
     * @return pointer to next object from buffer.
     */
    void *get(void);

    /**
     * Put (copy) an object into the buffer.  This blocks while the buffer
     * is full.
     * @param data to copy into the buffer.
     */
    void put(void *data);

    /**
     * Put (copy) an object into the buffer.
     * @param data to copy into the buffer.
     * @param timeout to wait if buffer is full.
     * @return true if copied, false if timed out while full.
     */
    bool put(void *data, timeout_t timeout);

    /**
     * Release must be called when we get an object from the buffer.  This
     * is because the pointer we return is a physical pointer to memory
     * that is part of the buffer.  The object we get cannot be removed or
     * the memory modified while the object is being used.
     */
    void release(void);

    /**
     * Copy the next object from the buffer.  This blocks until an object
     * becomes available.  Buffer is auto-released.
     * @param data pointer to copy into.
     */
    void copy(void *data);

    /**
     * Copy the next object from the buffer.  Buffer is auto-released.
     * @param data pointer to copy into.
     * @param timeout to wait when buffer is empty in milliseconds.
     * @return true if object copied, or false if timed out.
     */
    bool copy(void *data, timeout_t timeout);

    /**
     * Peek at pending data in buffer.  This returns a pointer to
     * objects relative to the head.  In effect it is the same as
     * get() for item = 0.
     * @param item to examine in buffer.
     * @return pointer to item or NULL if invalid item number.
     */
    void *peek(unsigned item);

    virtual void *invalid(void) const;

public:
    /**
     * Get the size of the buffer.
     * @return size of the buffer.
     */
    unsigned size(void);

    /**
     * Get the number of objects in the buffer currently.
     * @return number of objects buffered.
     */
    unsigned count(void);

    /**
     * Test if there is data waiting in the buffer.
     * @return true if buffer has data.
     */
    operator bool();

    /**
     * Test if the buffer is empty.
     * @return true if the buffer is empty.
     */
    bool operator!();
};

/**
 * Manage a thread-safe queue of objects through reference pointers.  This
 * can be particularly interesting when used to enqueue/dequeue reference
 * counted managed objects.  Thread-safe access is managed through a
 * conditional.  Both lifo and fifo forms of queue access  may be used.  A
 * pool of self-managed member objects are used to operate the queue.  This
 * queue is optimized for fifo access; while lifo is supported, it will be
 * slow.  If you need primarily lifo, you should use stack instead.
 * @author David Sugar <dyfet@gnutelephony.org>
 */
class __EXPORT Queue : protected OrderedIndex, protected Conditional
{
private:
    mempager *pager;
    LinkedObject *freelist;
    size_t used;

    class __LOCAL member : public OrderedObject
    {
    public:
        member(Queue *q, ObjectProtocol *obj);
        ObjectProtocol *object;
    };

    friend class member;

protected:
    size_t limit;

    virtual ObjectProtocol *invalid(void) const;

public:
    /**
     * Create a queue that uses a memory pager for internally managed
     * member objects for a specified maximum number of object pointers.
     * @param pager to use for internal member object or NULL to use heap.
     * @param number of pointers that can be in the queue or 0 for unlimited.
     * size limit.
     */
    Queue(mempager *pager = NULL, size_t number = 0);

    /**
     * Destroy queue.  If no mempager is used, then frees heap.
     */
    ~Queue();

    /**
     * Remove a specific object pointer for the queue.  This can remove
     * a member from any location in the queue, whether beginning, end, or
     * somewhere in the middle.  This also releases the object.
     * @param object to remove.
     * @return true if object was removed, false if not found.
     */
    bool remove(ObjectProtocol *object);

    /**
     * Post an object into the queue by it's pointer.  This can wait for
     * a specified timeout if the queue is full, for example, for another
     * thread to remove an object pointer.  This also retains the object.
     * @param object to post.
     * @param timeout to wait if queue is full in milliseconds.
     * @return true if object posted, false if queue full and timeout expired.
     */
    bool post(ObjectProtocol *object, timeout_t timeout = 0);

    /**
     * Examine pending existing object in queue.  Does not remove it.
     * @param number of elements back.
     * @return object in queue or NULL if invalid value.
     */
    ObjectProtocol *get(unsigned offset = 0);

    /**
     * Get and remove last object posted to the queue.  This can wait for
     * a specified timeout of the queue is empty.  The object is still
     * retained and must be released or deleted by the receiving function.
     * @param timeout to wait if empty in milliseconds.
     * @return object from queue or NULL if empty and timed out.
     */
    ObjectProtocol *fifo(timeout_t timeout = 0);

    /**
     * Get and remove first object posted to the queue.  This can wait for
     * a specified timeout of the queue is empty.  The object is still
     * retained and must be released or deleted by the receiving function.
     * @param timeout to wait if empty in milliseconds.
     * @return object from queue or NULL if empty and timed out.
     */
    ObjectProtocol *lifo(timeout_t timeout = 0);

    /**
     * Get number of object points currently in the queue.
     * @return number of objects in queue.
     */
    size_t count(void);
};

/**
 * Manage a thread-safe stack of objects through reference pointers.  This
 * Thread-safe access is managed through a conditional.  This differs from
 * the queue in lifo mode because delinking the last object is immediate,
 * and because it has much less overhead.  A pool of self-managed
 * member objects are used to operate the stack.
 * @author David Sugar <dyfet@gnutelephony.org>
 */
class __EXPORT Stack : protected Conditional
{
private:
    LinkedObject *freelist, *usedlist;
    mempager *pager;
    size_t used;

    class __LOCAL member : public LinkedObject
    {
    public:
        member(Stack *s, ObjectProtocol *obj);
        ObjectProtocol *object;
    };

    friend class member;

protected:
    size_t limit;

    virtual ObjectProtocol *invalid(void) const;

public:
    /**
     * Create a stack that uses a memory pager for internally managed
     * member objects for a specified maximum number of object pointers.
     * @param pager to use for internal member object or NULL to use heap.
     * @param number of pointers that can be in the stack or 0 if unlimited.
     */
    Stack(mempager *pager = NULL, size_t number = 0);

    /**
     * Destroy queue.  If no pager is used, then frees heap.
     */
    virtual ~Stack();

    /**
     * Remove a specific object pointer for the queue.  This can remove
     * a member from any location in the queue, whether beginning, end, or
     * somewhere in the middle.  This also releases the object.
     * @param object to remove.
     * @return true if object was removed, false if not found.
     */
    bool remove(ObjectProtocol *object);

    /**
     * Push an object into the stack by it's pointer.  This can wait for
     * a specified timeout if the stack is full, for example, for another
     * thread to remove an object pointer.  This also retains the object.
     * @param object to push.
     * @param timeout to wait if stack is full in milliseconds.
     * @return true if object pushed, false if stack full and timeout expired.
     */
    bool push(ObjectProtocol *object, timeout_t timeout = 0);

    /**
     * Get and remove last object pushed on the stack.  This can wait for
     * a specified timeout of the stack is empty.  The object is still
     * retained and must be released or deleted by the receiving function.
     * @param timeout to wait if empty in milliseconds.
     * @return object pulled from stack or NULL if empty and timed out.
     */
    ObjectProtocol *pull(timeout_t timeout = 0);

    /**
     * Examine an existing object on the stack.
     * @param offset to stack entry.
     * @return object examined.
     */
    ObjectProtocol *get(unsigned offset = 0);

    /**
     * Get number of object points currently in the stack.
     * @return number of objects in stack.
     */
    size_t count(void);

    const ObjectProtocol *peek(timeout_t timeout = 0);
};

/**
 * Linked allocator template to gather linked objects.  This allocates the
 * object pool in a single array as a single heap allocation, and releases
 * the whole pool with a single delete when done.  It is also threadsafe.
 * The types used must be derived of LinkedObject.
 * @author David Sugar <dyfet@gnutelephony.org>
 */
template <class T>
class linked_allocator : public LinkedAllocator
{
private:
    T* array;

public:
    inline linked_allocator(size_t size) : LinkedAllocator() {
        array = new T[size];
        for(unsigned i = 0; i < size; ++i)
            array[i].enlist(&freelist);
    }

    ~linked_allocator()
        {delete[] array;};

    inline T *get(void)
        {return static_cast<T *>(LinkedAllocator::get());};

    inline T *get(timeout_t timeout)
        {return static_cast<T *>(LinkedAllocator::get(timeout));};

    inline void release(T *node)
        {LinkedAllocator::release(node);};
};

/**
 * A templated typed class for buffering of objects.  This operates as a
 * fifo buffer of typed objects which are physically copied into the buffer.
 * The objects that are buffered are accessed from allocated buffer space.
 * As designed this may be used with multiple producer threads and one
 * consumer thread.  To use multiple consumers, one can copy the typed object
 * from the buffer through the get pointer and then call release.  The
 * copied object can then be used safely.  This is what the copy method is
 * used for.
 * @author David Sugar <dyfet@gnutelephony.org>
 */
template<class T>
class bufferof : public Buffer
{
public:
    /**
     * Create a buffer to hold a series of typed objects.
     * @param count of typed objects in the buffer.
     */
    inline bufferof(unsigned capacity) :
        Buffer(sizeof(T), capacity) {};

    /**
     * Get the next typed object from the buffer.  This blocks until an object
     * becomes available.
     * @return pointer to next typed object from buffer.
     */
    inline T *get(void)
        {return static_cast<T*>(get());};

    /**
     * Get the next typed object from the buffer.
     * @param timeout to wait when buffer is empty in milliseconds.
     * @return pointer to next typed object in the buffer or NULL if timed out.
     */
    inline T *get(timeout_t timeout)
        {return static_cast<T*>(get(timeout));};

    /**
     * Put (copy) a typed object into the buffer.  This blocks while the buffer
     * is full.
     * @param object to copy into the buffer.
     */
    inline void put(T *object)
        {put(object);};

    /**
     * Put (copy) an object into the buffer.
     * @param object to copy into the buffer.
     * @param timeout to wait if buffer is full.
     * @return true if copied, false if timed out while full.
     */
    inline bool put(T *object, timeout_t timeout)
        {return put(object, timeout);};

    /**
     * Copy the next typed object from the buffer.  This blocks until an object
     * becomes available.
     * @param object pointer to copy typed object into.
     */
    inline void copy(T *object)
        {copy(object);};

    /**
     * Copy the next typed object from the buffer.
     * @param object pointer to copy typed object into.
     * @param timeout to wait when buffer is empty in milliseconds.
     * @return true if object copied, or false if timed out.
     */
    inline bool get(T *object, timeout_t timeout)
        {return copy(object, timeout);};

    /**
     * Examine past item in the buffer.  This is a typecast of the peek
     * operation.
     * @param item in buffer.
     * @return item pointer if valid or NULL.
     */
    inline const T& at(unsigned item)
        {return static_cast<const T&>(Buffer::peek(item));};

    /**
     * Examine past item in the buffer.  This is a typecast of the peek
     * operation.
     * @param item in buffer.
     * @return item pointer if valid or NULL.
     */
    inline T&operator[](unsigned item)
        {return static_cast<T&>(Buffer::peek(item));};

    inline T* operator()(unsigned offset = 0)
        {return static_cast<T*>(Buffer::peek(offset));}
};

/**
 * A templated typed class for thread-safe stack of object pointers.  This
 * allows one to use the stack class in a typesafe manner for a specific
 * object type derived from Object rather than generically for any derived
 * object class.
 * @author David Sugar <dyfet@gnutelephony.org>
 */
template<class T>
class stackof : public Stack
{
public:
    /**
     * Create templated stack of typed objects.
     * @param memory pool for internal use of stack.
     * @param size of stack to construct.  Uses 0 if no size limit.
     */
    inline stackof(mempager *memory, size_t size = 0) : Stack(memory, size) {};

    /**
     * Remove a specific typed object pointer for the stack.  This can remove
     * a member from any location in the stack, whether beginning, end, or
     * somewhere in the middle.  This releases the object.
     * @param object to remove.
     * @return true if object was removed, false if not found.
     */
    inline bool remove(T *object)
        {return Stack::remove(object);};

    /**
     * Push a typed object into the stack by it's pointer.  This can wait for
     * a specified timeout if the queue is full, for example, for another
     * thread to remove an object pointer.  This retains the object.
     * @param object to push.
     * @param timeout to wait if queue is full in milliseconds.
     * @return true if object pushed, false if queue full and timeout expired.
     */
    inline bool push(T *object, timeout_t timeout = 0)
        {return Stack::push(object);};

    /**
     * Get and remove last typed object posted to the stack.  This can wait for
     * a specified timeout of the stack is empty.  The object is still retained
     * and must be released or deleted by the receiving function.
     * @param timeout to wait if empty in milliseconds.
     * @return object from queue or NULL if empty and timed out.
     */
    inline T *pull(timeout_t timeout = 0)
        {return static_cast<T *>(Stack::pull(timeout));};

    /**
     * Examine last typed object posted to the stack.  This can wait for
     * a specified timeout of the stack is empty.
     * @param timeout to wait if empty in milliseconds.
     * @return object in queue or NULL if empty and timed out.
     */
    inline const T *peek(timeout_t timeout = 0)
        {return static_cast<const T *>(Stack::peek(timeout));};

    inline T* operator()(unsigned offset = 0)
        {return static_cast<T*>(Stack::get(offset));}

    /**
     * Examine past item in the stack.  This is a typecast of the peek
     * operation.
     * @param offset in stack.
     * @return item pointer if valid or NULL.
     */
    inline const T& at(unsigned offset = 0)
        {return static_cast<const T&>(Stack::get(offset));};

    /**
     * Examine past item in the stack.  This is a typecast of the peek
     * operation.
     * @param offset in stack.
     * @return item pointer if valid or NULL.
     */
    inline const T& operator[](unsigned offset)
        {return static_cast<T&>(Stack::get(offset));};

};

/**
 * A templated typed class for thread-safe queue of object pointers.  This
 * allows one to use the queue class in a typesafe manner for a specific
 * object type derived from Object rather than generically for any derived
 * object class.
 * @author David Sugar <dyfet@gnutelephony.org>
 */
template<class T>
class queueof : public Queue
{
public:
    /**
     * Create templated queue of typed objects.
     * @param memory pool for internal use by queue.
     * @param size of queue to construct.  Uses 0 if no size limit.
     */
    inline queueof(mempager *memory, size_t size = 0) : Queue(memory, size) {};

    /**
     * Remove a specific typed object pointer for the queue.  This can remove
     * a member from any location in the queue, whether beginning, end, or
     * somewhere in the middle. This releases the object.
     * @param object to remove.
     * @return true if object was removed, false if not found.
     */
    inline bool remove(T *object)
        {return Queue::remove(object);};

    /**
     * Post a typed object into the queue by it's pointer.  This can wait for
     * a specified timeout if the queue is full, for example, for another
     * thread to remove an object pointer.  This retains the object.
     * @param object to post.
     * @param timeout to wait if queue is full in milliseconds.
     * @return true if object posted, false if queue full and timeout expired.
     */
    inline bool post(T *object, timeout_t timeout = 0)
        {return Queue::post(object);};

    /**
     * Get and remove first typed object posted to the queue.  This can wait for
     * a specified timeut of the queue is empty.  The object is still retained
     * and must be released or deleted by the receiving function.
     * @param timeout to wait if empty in milliseconds.
     * @return object from queue or NULL if empty and timed out.
     */
    inline T *fifo(timeout_t timeout = 0)
        {return static_cast<T *>(Queue::fifo(timeout));};

    /**
     * Get and remove last typed object posted to the queue.  This can wait for
     * a specified timeout of the queue is empty.  The object is still retained
     * and must be released or deleted by the receiving function.
     * @param timeout to wait if empty in milliseconds.
     * @return object from queue or NULL if empty and timed out.
     */
    inline T *lifo(timeout_t timeout = 0)
        {return static_cast<T *>(Queue::lifo(timeout));};

    /**
     * Examine past item in the queue.  This is a typecast of the peek
     * operation.
     * @param offset in queue.
     * @return item pointer if valid or NULL.
     */
    inline const T& at(unsigned offset = 0)
        {return static_cast<const T&>(Queue::get(offset));};

    /**
     * Examine past item in the queue.  This is a typecast of the peek
     * operation.
     * @param offset in queue.
     * @return item pointer if valid or NULL.
     */
    inline T& operator[](unsigned offset)
        {return static_cast<T&>(Queue::get(offset));};

    inline T* operator()(unsigned offset = 0)
        {return static_cast<T*>(Queue::get(offset));}
};

/**
 * Convenience type for using thread-safe object stacks.
 */
typedef Stack stack_t;

/**
 * Convenience type for using thread-safe object fifo (queue).
 */
typedef Queue fifo_t;

END_NAMESPACE

#endif