Revision history for Perl extension IPC::Shareable.

1.15 UNREL
    - Refactor how we initialize $VERSION. It's no longer in a BEGIN block. That
      broke Dist::Mgr
    - Fixes #60: Fix FETCH deadlock when inner child re-decode acquires SH lock
      against LOCK_EX cascade held by _lock_children
    - Fix OpenBSD 64-bit shmid_ds binary layout (verified via offsetof on 7.4):
      segsz is int (4B not 8B), nattch is short (2B), and struct has nanosecond
      fields between time_t values.  Updated t/80-SharedMem.t synthetic test and
      shm_segments() segsz extraction to match.
    - Added OpenBSD test VM infrastructure
    - t/20-lock_operation.t: probe for adequate semaphore resources before
      running, skip gracefully on low-limit platforms (OpenBSD semmni=10).
      Added periodic _end() cleanup calls so peak semaphore usage stays within
      the default limit on OpenBSD.
    - Added 'testing' flag; allows bulk cleanup of leaked segs/sems from a
      previous test run

1.14     2026-05-22
    - Modify remove() to properly catch a non "0 but true" case when trying
      to destroy segments and semaphores so warnings are displayed properly
    - remove() now leaves the global and process registers intact if the destroy
      operation fails
    - Rename _mg_tie() to _magic_tie()
    - Rename _is_kid() to _is_child()
    - In IPC::SharedMem, removed leading underscore from object attributes
    - Parameter list in IPC::SharedMem::new() is now in the form of a hash
    - Code refactoring in IPC::SharedMem
    - Add POD for IPC::SharedMem
    - SharedMem::remove() now returns 1 on '0 but true' and 0 otherwise
      that was preventing matches from happening, and broke JSON
    - ipcs() now ignores lines that don't include an actual key
    - Add data() method to SharedMem. This strips off the NULL pad bytes from
      shmread()
    - Added key_hex() to SharedMem. Will allow for easier troubleshooting when
      using ipcs (closes #32)
    - Added SharedMem::stat(); returns a new object that contains the related
      info about the actual shared memory segment
    - Fixes #49; Logic error from old implementation of JSON
    - Fixes #47; Clean up broken code in old _decode_json()
    - Fixes #41; JSON serializer not handling nested data structures properly
    - Closes #52; Add tests and POD for SharedMem::stat struct methods
    - Added SharedMem::stats(), return an href of all segment stats
    - Closes #48; All tests now run unconditionally; there is no more
      CI_TESTING flag required
    - Greatly simplify the FIRSTKEY and NEXTKEY shared hash ops; removed the
      _iterating flag complexity and replaced it with an _hkey_list instead
    - Fixes #38; Fixed issue where the global_register was not being populated
      if a data access hadn't happened yet, causing leaked segments upon
      cleanup. This fix eliminated the weird 'Dumper' hack
    - Add new scripts/flush_ipc.sh script that cleans out all segments and
      semaphores from the system for the current user
    - Closes #28; Add link to Script::Singleton in singleton() POD
    - Closes #24; lock() now allows a cref parameter. If a LOCK_EX lock can be
      acquired, we will set the lock, execute the subroutine, then release the
      lock
    - 'tidy' attribute now defaults to true
    - All unit tests do a check for leaked segments and semaphores at their
      conclusion. Also, when running 'make test' it compares the numbers before
      and after and doubly makes sure there are no leaks
    - Closes #51; Better document that the 'size' attribute is for each segment,
      and not the overall size of all the data. Also emphasize that each nested
      data structure requires an additional segment, they aren't all stashed
      into a single one
    - Added uuid(), sets an internal UUID for each tied object (primarily used
      for troubleshooting)
    - Fixes #50; Added enforced locking, with optional warning
    - Correct five areas in clean/delete routines where segments may have been
      able to leak
    - Removed redundant _global_register checks in STORE, FETCH, PUSH; _tie()
      already registers unconditionally
    - Add ref() check before _is_child(); skips the function call reftype()
      entirely for plain scalar values in FETCH, CLEAR, and DELETE
    - Add ref() check before _need_tie(); same pattern in all three STORE
      branches
    - _type_int numeric dispatch; string eq comparisons on every operation
      replaced with == against integer constants in STORE, FETCH, and CLEAR
    - Major POD enhancements/cleanup
    - Renamed ipcs() to seg_count() as it's far more explanatory
    - Add new method sysv_info() which if the system provides it, retrieves all
      information related to the SYSV infrastructure (limits etc)
    - Closes #45; We now accept a hex-based value as the key
    - Added shm_segments(); fetches raw data about all segments that had been
      created by this distribution
    - Added unknown_segments(); returns an aref of all segment keys (in hex
      string format) for segments we've created but are no longer registered to
      any known process
    - Closes #39; remove() now accepts a key, and can remove the segment and
      semaphores related to that key, even if it isn't related to this
      distribution
    - Updated CI so we get a test run on an i386 Ubuntu container to test
      32-bit platforms
    - Fix issue when using JSON serializer where it wasn't properly handling
      scalar references properly (eg. creating a tie with a hashref)
    - Enhanced much of the test suite to test both Storable and JSON serializers
    - Much work in order to add provisions so that shm counting and tracking
      works on FreeBSD
    - Add FreeBSD VM config and unit test runner in ci/ dir
    - Removed the archaic _debug() and _trace functions
    - Enhanced 'protected' segments; we now use a semaphore to mark a segment as
      protected (SEM_PROTECTED), and all processes that load this segment will
      inherit the protected status
    - Add sem_map(); outputs a text representation of the segment/semaphore
      mappings
    - Added consistent naming for all four semaphores: SEM_EXISTS, SEM_READERS,
      SEM_WRITERS, and SEM_PROTECTED
    - Default serializer now JSON; Added check for backwards compatibility that
      if JSON _decode() fails, we then attempt a Storable _thaw()
    - Added sem_count(); behaves like seg_count() but for semaphores. Also
      updated tests to ensure no straggling semaphores are left behind
    - All LOCK_EX and LOCK_SH locks are now applied to all child segments when
      the lock is first instantiated on the tied object. Both of them are rolled
      out in reverse order from the lowest-level child upwards when the lock is
      released
    - New attributes for updated locking mechanisms: enforced_write_locking,
      enforced_read_locking, violated_write_lock_warn and
      violated_read_lock_warn. All enabled by default
    - Fixes #11; On non-English locales on perl 5.20 and below, checking $! for
      strings in certain cases was failing and sending code down the wrong path.
      The fix was to replace the comparisons with $!{ERRNO_CONST} variables
      instead (eg. $!{EEXIST}, $!{ENOMEM}, $!{ENOSPC}) which are
      locale-independent
    - Add Solaris (including OmniOS/illumos) support for shm_segments(),
      seg_map(), and SharedMem stat()/stats() methods by providing
      Solaris-specific shmid_ds unpack templates
    - Add explicit use Errno so that $!{ENOMEM} and $!{EEXIST} checks work
      reliably on all platforms (Solaris Perl builds did not populate these
      keys in the %! tied hash without the module loaded)
    - Complete VM unit testing framework with scripts and README for FreeBSD,
      Linux i386 and Solaris (32 and 64 bit)
    - Replace regex-based null-byte stripping in SharedMem::data() with more
      efficient index+substr
    - SharedMem::stats() now calls stat() once and reuses it, avoiding 11
      redundant shmctl(IPC_STAT) syscalls
    - _encode_json_prepare() now short-circuits for structures with no
      IPC::Shareable child refs, avoiding a full hash/array copy on every encode
    - _decode_json_restore() hoists ref($prev) checks outside hot loop
    - Added XS implementation of _is_child() for faster child-knot detection;
      falls back to pure Perl _is_child_pp() if the compiled XS can't be loaded.
      The XS function _is_child_xs inspects SV magic directly in C, avoiding
      Scalar::Util::reftype, tied(), and ref() calls
    - Added t/75-is_child_xs.t to test both XS and pure-Perl _is_child paths
    - Added IPC_SHAREABLE_NO_XS env var to force pure-Perl mode for verifying
      operation on systems without a C compiler
    - Eliminated redundant second ipcs -m shell-out in seg_map(); get id mapping
      from shm_segments() result instead
    - Replaced all backtick shell-outs with open('-|', @cmd) pipe-open to bypass
      /bin/sh and halve the fork count
    - Rewrote _lock_children() from recursive to iterative (manual stack) to
      eliminate Perl call-stack overhead on deeply nested structures; simplified
      interface returns an arrayref instead of passing accumulator/seen refs
    - Fix STORE child-segment leak: old child references were silently
      discarded without removing shm segments/semaphores. STORE now calls
      _remove_child() before overwriting. Extracted the common pattern into
      _remove_child() to deduplicate across DELETE, CLEAR, and STORE.
    - Remove the 'tidy' attribute and _reset_segment() internals. The STORE fix
      made _reset_segment() a no-op that only produced double-removal warnings.
    - Fix t/25-fetch_read_warn.t pipe synchronization so the parent blocks until
      the child confirms LOCK_EX, instead of a blind sleep
    - shm_segments() now probes the 14-byte 'IPC::Shareable' tag before pulling
      the full segment into Perl, avoiding gigabyte allocations for foreign segs
    - Drop unconditional use-time srand(); _shm_key_rand collisions are already
      caught by the IPC_EXCL re-check loop, so reseeding callers' RNG is needless
    - Remove redundant Data::Dumper imports from Shareable.pm and SharedMem.pm
    - Fix _shm_key() off-by-one: overflow-correction now triggers on
      crc32 == MAX_KEY_INT_SIZE, making the post-subtraction key==0 croak
      actually reachable
    - Test coverage additions: unknown_segments() via fork+exit, sysv_info() on
      Solaris, JSON->Storable carp format, both write-lock flags disabled,
      _shm_key() key==0 croak (Mock::Sub on crc32), IPC_PRIVATE + JSON nested
      tie, STORE scalar-ref over previous \$undef
    - Fix t/73-internal.t cross-version: qr// reftype differs between 5.10 and
      5.12+, so use a CODE ref to exercise the _encode_json_prepare fallthrough
    - Bump prereq of Test::More to 0.98 due to 5.10.1 using 0.94 by default

1.13    2022-10-11
    - In singleton(), do a check whether class was sent in. There was a shifting
      issue if called with IPC::Shareable::singleton() as opposed to
      IPC::Shareable->singleton()
    - When an exclusive collision occurs and both 'graceful' and 'warn' are set,
      the warning thrown now includes the segment/semaphore key in use. This
      makes it easier to clean things up with 'ipcrm'

1.12    2022-03-13
    - Add tests in t/07-new.t to test how using tied() against a dereferenced
      variable returned from new() allows access to the underlying
      IPC::Shareable object
    - Reworked how spawn() and unspawn() manage things internally
    - POD updates, fixes and clarifications
    - Removed spawn() and unspawn(). There's really no need for these as one
      can simply create but not destroy

1.11    2022-03-07
    - Fix certain tests so they don't throw if we bail early

1.10    2022-03-07
    - Fix issue where if segments were created underneath of a parent by an
      external process other than the process that created the parent, the
      global register wasn't being updated, therefore those segments weren't
      being removed when calling clean_up_all()
    - All test files now check number of segments before and after the entire
      script has run, verifying that all segments were cleaned up ok
    - The test suite itself in its entirety makes sure that all segments
      created during the suite run are cleaned up properly
    - Added CI_TESTING=1 to coverage CI tests

1.09    2022-03-06
    - Made 81-fork_dup_rand_keys.t developer only (but still need to figure out
      why it only fails on FreeBSD)

1.08    2022-03-04
    - Added 'protected' option and clean_up_protected(). If set, the cleanup
      methods, nor the automatic 'destroy' functionality will remove the segment
      the option was set in, nor any children created underneath of it. A call
      to clean_up_protected() is required to remove them
    - Updated attribute tests to include all available options
    - _shm_key_rand() now checks EXCLUSIVE_CHECK_LIMIT times to find a key for
      a free segment. It croaks if not
    - Added _shm_key_rand_int() so we can mock it to test the dup random key
      checks
    - Added build prereq of Mock::Sub to test the random key function

1.07    2022-03-04
    - When running in forked environments, _shm_key_rand() was consistently
      returning the same 'random' key to each forked process. We've fixed this
      issue, and added tests for it (fixed by adding a call to srand() before
      rand)
    - Move $SIG{CHLD} handlers to spawn() and unspawn() instead of having them
      global (fixes #15)
    - t/65-seg_size.t fails on 32-bit perls; Add a check and bail if we're on
      a perl < 64-bit (fixes #14)

1.06    2021-09-08
    - Fix significant bug where at least on MacOS, if we generated a CRC of a
      key that was greater than 0x80000000, it would round down the key to that
      number exactly, causing duplicates, and incorrect segment access
    - Added new() method, returns a reference (default hash) without having to
      do the tie() directly
    - Fix issue in JSON decoder where an empty JSON string may have caused
      decode failure
    - Modify t/65-seg_size.t beyond RAM max test to cover varying error messages
      on differing OSs
    - Renamed t/67-out_of_memory.t as the tests are related to exhausting SHM
      slots, not RAM

1.05    2021-07-16
    - Bump prereq version of Test::SharedFork to 0.35
    - Added ability to use JSON as the serializer
    - Added ipcs()
    - Added test to ensure we croak if data size is greater than segment size
    - Added 'tidy' attribute, removes unneeded nested structure segments
    - In SharedMem, added _key attribute, and added set/get methods
    - Changed key generation from using padding, pack and unpack to using
      String::CRC32's crc32(), which allows arbitrary, unpadded strings
    - Added attributes() allows fetching one, or all of the object's atttributes
    - Added 'limit' attribute, by setting false, allows a user to set a segment
      size larger than our internal 1GB default
    - Cleaned up exception throwing (particularly if seg size eats up all
      memory, we throw an appropriate message)
    - Display proper exception if we try to exhaust all available shared memory
      segments (fixes #3)

1.04    2021-06-28
    - Skip unspawn tests for perls with -Duselongdouble, as Storable is not
      compatible storing/retrieving such numbers (closes #5)

1.03    2021-06-25
    - Add newline to singleton() warn so that it doesn't print out trace info

1.02    2021-06-25
    - Remove erroneous listing from MANIFEST
    - Work around issue in t/65-seg_size.t where MacOS and FreeBSD don't have
      the -i flag to ipcs (thanks for the PR, Roland Walker!)
    - Added singleton(), ensures that only a single instance of a script can
      run at any given time
    - Added tests to ensure we croak() if create is not set and the segment
      doesn't yet exist
    - Fix POD issue where we stated exclusive returns undef instead of croaking
      (fixes #10)
    - Change 'perl' shell call to $^X in t/71-unspawn.t (fixes #6)

1.01    2021-06-24
    - Added 'graceful' flag option. With exclusive, if a second process
      attempts to tie an exclusive segment, we exit gracefully instead of
      croaking

1.00    2021-06-09
    - Project adopted by Steve Bertrand
    - Added global_register() and process_register() to return the
      registries of active segments and semaphores
    - Added seg() and sem() methods, returns the structure of a shared
      memory segment and a sempahore respectively
    - Added initial "persist" hash variables. Separate processes (even
      multiple files in multiple windows) can share a variable, and it'll
      remain available even after all processes exit. The variable will be
      re-attached if the same shared segment key is used in subsequent runs
    - Reversed order of Changes file
    - Removed trace() and debug() code for ease of reading
    - Improved exception/error messages, added exception testing, reduced
      and minimized the number of exceptions actually uncaught
    - Significant POD cleanup
    - 100% rewrite of all test files, and added a slew of new ones, all
      using Test::More
    - Add build requirement of Test::SharedFork to handle the out of
      sequence fork() tests in t/35-clean.t and t/30-lock_operations
    - Major POD updates
    - Added tests to prove that RT 123057 isn't really an issue (ie. segment
      size parameter works correctly)

0.61  Mon Oct  8 00:27:39 2012
    - Added patch from Frank Lichtenheld fixing IPC::Shareable's dependence
      on the presence of a perl bug which is no longer present in
      perl >= 5.10
    - Fixed bug reported by Dan Harbin where the FETCH operation on a tie()d
      string containing HASH, ARRAY, or SCALAR fails because it was using
      the stringification of the data to determine what kind of reference
      it was.  Now using Scalar::Util::reftype
    - Added missing dependency on IPC::Semaphore to Makefile.PL (reported
      by Adrian Issott)
    - Added a 'sleep 1' in a test that was hanging on certain systems
      due (possibly) to two alarm signals coming too quickly to the
      child process.  From Ton Voon.

0.60  Mon Mar  5 15:20:18 EST 2001
    - Lee Lindley (lee.lindley@bigfoot.com) added the _was_changed
      optimization, improved the locking functionality, fixed
      numerous bugs, and generally cleaned things up; thanks.
    - Removed support for "no" as a false value in arguments;
      thanks to Dave Rolsky <autarch@urth.org>

0.54  Mon Jan  8 11:52:28 EST 2001
    - Fix to allow IPC::Shareable to work with 1.0.* versions of
      Storable

0.53  Tue Nov 14 00:33:35 EST 2000
    - Fixed race condition in test suite causing intermitent
      failures.
    - Better checking for success of calls to Storable::thaw();
      thanks to Raphael Manfredi <Raphael_Manfredi@pobox.com>.

0.52  Thu Sep 14 12:30:17 EDT 2000
    - Now STORE, PUSH, POP, etc all call _thaw() before doing
      their business.
    - Refined SIGALRM handlers in test scripts
    - Fixed concurrency issues affecting tied arrays and hashes;
      thanks to thanks to Robert Emmery <roberte@netscape.com>,
      Terry Ewing <terry@intevo.com>, Tim Fries
      <timf@dicecorp.com>, and Joe Thomas <jthomas@women.com>.
    - Doc fixes thanks to Paul Makepeace
      <Paul.Makepeace@realprogrammers.com>

0.51  Fri May  5 23:47:06 EDT 2000
    - Fixed bug that would cause IPC::Shareable::BUF_SIZ to be
      ignored; thanks to Robert Emmery <roberte@netscape.com> and
      Mohammed J. Kabir <kabir@intevo.com> for reporting.
    - Stopped tests from leaking shm segments
    - Added test of argument parsing
    - doc fixes

0.50 Tue Mar 21 11:56:32 EST 2000
    - Complete rewrite incorporating the following changes.
    - Requires 5.00503.  This allowed the module to get rid of the
      global cache for shared memory segments; each Shareable
      object now carries around its own data.
    - 5.00503 also allowed tied arrays to be implemented
    - Shared memory segments can no longer be of infinite length
      thereby reducing the amount of code in the module by a
      factor of 2.
    - Uses IPC::Shareable::SharedMem class for accessing
      shared memory.
    - Uses IPC::Semaphore module for accessing semaphores.
    - Completely revisited the way references are dealed with: all
      referenced thingies are now automagically tied to shared
      memory.
    - Constants now imported from IPC::SysV; Shareable.xs is gone
    - Rewrote test suite and moved into t subdirectory
    - Updated man page

 0.30 Mon Jan 19 11:13:41 EST 1998
    - Added SEM_UNDO to semop() calls; Maurice Aubrey.
    - Fixed some bugs in the locking code; Maurice Aubrey.
    - Made calls to debug() conditional for efficency; Maurice Aubrey.
    - Fixed a signal handler in test.pl; Maurice Aubrey.

0.29  Mon Jan 12 13:49:42 EST 1998
    - $MAXVER patch for when the version semaphore reaches its limit
      and rolls back over to 0; Maurice Aubrey <maurice@hevanet.com>.
    - patch to quieten things down under -w; Doug MacEachern
      <dougm@telebusiness.co.nz>

0.28  Wed Oct 22 14:59:08 EDT 1997
    - cleaned up the way thingys are magically tied; Ben Sugars.
    - moved many subroutines so that they are auto-loaded; Ben
      Sugars.
    - updated man page; Ben Sugars.

0.26  Mon Oct 20 10:06:43 EDT 1997
    - fixed bug regarding assigning a reference to an empty
      hash to a tied variable.  Thanks to Jason Stevens.

0.25  Tue Oct  7 14:41:49 EDT 1997
    - added more checking of sem*() and shm*() return values;
      Michael Stevens and Ben Sugars.
    - added shlock and shunlock; Ben Sugars.
    - fixed bug that would cause modifications of magically
      referenced thingys to fail.  Thanks to Maurice Aubrey

0.20  Thu Aug 28 15:13:46 EDT 1997
    - added ability to magically create ties to implicitly
      referenced thingys; Ben Sugars.

0.18  Thu Aug 28 09:12:30 EDT 1997
    - fixed garbage collection bug; Ben Sugars.  Thanks to
      Michael Stevens <michael@imaginet.co.uk> for the patch.

0.17  Wed Aug 27 15:57:11 EDT 1997
    - fixed some bugs in &parse_argument_hash; Ben Sugars.

0.16  Mon Aug 11 16:10:54 EDT 1997
    - new shared memory segments now initialized with null
      values; Ben Sugars.

0.15  Fri Aug  8 15:45:29 EDT 1997
    - implemented locking using semaphores; Ben Sugars.

0.12  Thu Aug  7 14:47:42 EDT 1997
    - various bug fixes; Ben Sugars.

0.11  Wed Aug  6 10:14:49 EDT 1997
    - initial implementation of semaphores for versioning and
      caching; Ben Sugars.

0.10  Fri Aug  1 13:32:52 EDT 1997
    - can now tie both scalars and hashes of arbitrary length;
      Ben Sugars.

0.05  Wed Jul 30 15:02:31 EDT 1997
    - scalars can now be tied; Ben Sugars.

0.01  Wed Jul 30 09:00:53 1997
    - original version; created by h2xs 1.18.
