Merge branch 'release-2.140.92' into dev
[feisty_meow.git] / nucleus / library / application / shared_memory.h
1 #ifndef SHARED_MEMORY_CLASS
2 #define SHARED_MEMORY_CLASS
3
4 /*****************************************************************************\
5 *                                                                             *
6 *  Name   : shared_memory                                                     *
7 *  Author : Chris Koeritz                                                     *
8 *                                                                             *
9 *******************************************************************************
10 * Copyright (c) 2002-$now By Author.  This program is free software; you can  *
11 * redistribute it and/or modify it under the terms of the GNU General Public  *
12 * License as published by the Free Software Foundation; either version 2 of   *
13 * the License or (at your option) any later version.  This is online at:      *
14 *     http://www.fsf.org/copyleft/gpl.html                                    *
15 * Please send any updates to: fred@gruntose.com                               *
16 \*****************************************************************************/
17
18 #include <basis/contracts.h>
19 #include <filesystem/byte_filer.h>
20 #include <processes/rendezvous.h>
21
22 namespace application {
23
24 //! Implements storage for memory that can be shared between threads.
25 /*!
26   Provides a means to create shared memory chunks and access them from
27   anywhere in a program or from cooperating programs.
28 */
29
30 class shared_memory : public virtual basis::root_object
31 {
32 public:
33   shared_memory(int size, const char *identity);
34     //!< a shared chunk of the "size" specified will be created.
35     /*!< it is named by the "identity" string.  that "identity" uniquely
36     points to one shared chunk on this machine.  note that if this object is
37     the first to create the chunk of memory, then all of the contents are
38     initialized to zero.  this can be used to determine if the chunk needs
39     higher level, application-specific initialization. */
40
41   virtual ~shared_memory();
42     //!< cleans up the shared bit of memory as far as we're concerned.
43     /*!< if some other instance still has it opened, then it isn't
44     destroyed for real yet. */
45
46   DEFINE_CLASS_NAME("shared_memory");
47
48   bool valid() const { return _valid; }
49     //!< this must be true for the shared_memory to be usable.
50     /*!< if it's false, then the memory chunk was never created. */
51
52   int size() const { return _size; }
53     //!< returns the size of the shared chunk of memory.
54
55   const basis::astring &identity() const;
56     //!< provides a peek at the name that this chunk was constructed with.
57
58   bool first_usage(basis::abyte *locked_memory, int max_compare);
59     //!< returns true if the "locked_memory" was just created.
60     /*!< that is assuming that a user of the shared memory will set the first
61     "max_compare" bytes to something other than all zeros.  this is really
62     just a test of whether bytes zero through bytes "max_compare" - 1 are
63     currently zero, causing a return of true.  seeing anything besides zero
64     causes a false return. */
65
66   basis::abyte *lock();
67     //!< locks the shared memory and returns a pointer to the storage.
68     /*!< the synchronization supported is only within this program; this type
69     of shared memory is not intended for access from multiple processes,
70     just for access from multiple threads in the same app. */
71
72   void unlock(basis::abyte * &to_unlock);
73     //!< returns control of the shared memory so others can access it.
74     /*!< calls to lock() must be paired up with calls to unlock(). */
75
76   static basis::astring unique_shared_mem_identifier(int sequencer);
77     //!< returns a unique identifier for a shared memory chunk.
78     /*!< the id returned is unique on this host for this particular process
79     and application, given a "sequencer" number that is up to the application
80     to keep track of uniquely.  the values from -100 through -1 are reserved
81     for hoople library internals. */
82
83 private:
84   processes::rendezvous *_locking;  //!< protects our shared memory.
85 #ifdef __UNIX__
86   int _the_memory;  //!< OS index of the memory.
87 #elif defined(__WIN32__)
88   void *_the_memory;  //!< OS pointer to the memory.
89 #endif
90   bool _valid;  //!< true if the memory creation succeeded.
91   basis::astring *_identity;  //!< holds the name we were created with.
92   int _size;  //!< size of memory chunk.
93
94   // these do the actual work of getting the memory.
95   basis::abyte *locked_grab_memory();
96   void locked_release_memory(basis::abyte * &to_unlock);
97
98   static basis::astring special_filename(const basis::astring &identity);
99     //!< provides the name for our shared memory file, if needed.
100
101   // forbidden.
102   shared_memory(const shared_memory &);
103   shared_memory &operator =(const shared_memory &);
104 };
105
106 } //namespace.
107
108
109 #endif  // outer guard.
110