SYSV IPC - Unix System V interprocess communication
SYSV IPC - uses SHM for data sharing, SEM for access control
"best effort delivery": FLCOMMS gives you the value "right now";
not a messaging protocol,
Describe features: lock-free read/write synchronization,
write access control,
Common usage scenario: all communicating parties
decide beforehand on the layout and contents of each data block
Note transparency:
Each data block is a white box;
one program might see this as an array of DOUBLEs,
another might see it as a compound data structure;
Scope sees it as a variable list.
NETFLC does care what type of data is stored in the block so
that it can serialize/deserialize it properly.
Emphasize that model variables referenced in attached variable lists
are not automatically synchronized with shared memory
Note ASCII "straight double quote" characters in APCTL("SYNC");
not `, ', '', or ``.
Reminder: flcomms is invoked from the Unix shell prompt
(not from Scope, X/Analysis, ...)
Column 1: directory entry #;
column 2: flags bitmap, numeric form;
column 7: position of data block in SHM segment.
Ought to just get rid of these columns, they aren't useful.
The s= (serial number field) can be very useful in debugging -
if it's not incrementing, something is probably wrong
flcomms -h is the only one you need to remember.
Be careful with flcomms -r on Linux:
the shared memory key will be unavailable until
all attached processes have exited.
There doesn't seem to be a way to list which processes
are attached.
flc_detach() can be registered as an atexit(3) handler.
FLCOMMS library doesn't do this by default since this may conflict
with application policy (e.g., multi-process or multi-thread)
Calling flc_detach() is very important.
flc_detach() automatically releases all open handles.
Return value of flc_read, flc_write -
flc_read returns NULL on error, ptr to internal buffer on success.
flc_write returns -1 on error, +1 on success.
Not much can go wrong with flc_write, though for debugging
purposes one should check return value anyway.
flc_read can fail - intermittent failures to be expected,
persistent errors need to be debugged.
Q: why must size be specified for flc_open() and for flc_read()/write()?
A: Good practice in C.
Remember to check return values of flc_open() for NULL
It is not necessary to call flc_ready() before flc_read()
You will get EINVAL during debugging.
flcomms -c will not release write locks if the owner PID is
still active.
ETIME is fairly rare (but even if there's only a 0.001%
chance of it happenning, it's practically guaranteed to happen
eventually.) Most often happens on single-CPU systems when
the writer gets scheduled out in the middle of an flc_write() call.
If it happens too frequently, the writer may be starving the reader -
write less frequently.
If it happens persistently -- flcomms -l s=serial number field
is an odd number that doesn't change -- writer has been killed in the
middle of a write() call; use flcomms -c.
Data block names are silently truncated
NETFLC is the main reason why FLC_TYPE_ flags are needed
Note format conversions: e.g., SGI machines and Pentium-based PCs
Single-writer discipline can break down with netflc -- there
is a race condition (Ex: process 1 on host A acquires local write lock;
process 2 on host B acquires local write lock; netflc starts on both
hosts.)
By default, nothing to configure -- should work out-of-box.
Reminder: magic number reported by flcomms -l is
in hexadecimal - use 0x.... in C code
Best to use 0 as magic number during initial testing and development,
only set to final (nonzero) value when app is up and running.
flc_open -- which acquires a data block handle --
is thread-safe because it locks the FLCOMMS directory in
shared memory; that lock suffices to protect the in-memory
data structures from other threads.
Mention coherent read within data blocks
(always get full frame of data)