Harvid daemonizes and does not write anything
to stdout/err. as opposed to select(), poll() on
macOS does not return when the child process
terminates or is killed.
However poll() on an invalid FD does throw an
error and POLLNVAL is set.
glib atomic operations include a complete act as a full
compiler and (where appropriate) hardware memory barrier.
std::atomic<> allows dedicated acquire and release barrier
semantics which are not available with glib.
While POSIX defines a single contiguous range of numbers that
determine a thread's priority. Win32 defines priority classes
and priority levels relative to these classes.
pthread maps those to -15 .. +15 with the top six ones
corresponding to REALTIME_PRIORITY_CLASS and max being
THREAD_PRIORITY_TIME_CRITICAL
Note that the PA backend can USE_MMCSS_THREAD_PRIORITIES
and PBD::MMCSS::set_thread_characteristics() directly for
the I/O threads.
Previously the following were treated as equal
"MIDI_foo" == "MIDI bar"
So std::map<> PortManager::_ports and PortEngineSharedImpl:_ports
could only have either. This resulted in missing ports
and missing calls to existing ports in cycle_start().
This mainly affected MIDI tracks with imported files, since there
is "MIDI Clock in", and imported files result in tracks
"MIDI_file-name".
This issue was introduced in 6.6-200-g60ff3ef764
select(2) can only handle file descriptors up to 1024, and there are fairly easy to reproduce
cases where the file descriptor used here is larger than that.
RegionInsertDrag or Consolidate Range or any other operation
calling Playlist::add_region() previously triggered RangesMoved()
which resulted in DiskReader::move_processor_automation()
NB. insert + ripple still moves automation correctly.
strictly speaking the include is not needed here since
g_atomic_compat.h includes glib.h. However it is idempotent,
the file does use glib methods, and g_atomic_compat.h may
one day be removed again.
Previously an empty RegionList was used (auto-partition
changes were never collected at rec-stop), furthermore
auto-partitioned regions do not have an old ARDOUR::AutomationList
(fade in/out) property (_have_old is false).
"While 'atomic' has a volatile qualifier, this is a historical
artifact and the pointer passed to it should not be volatile."
Furthermore "It is very important that all accesses to a
particular integer or pointer be performed using only this API"
(from https://developer.gnome.org/glib/2.68/glib-Atomic-Operations.html)
Hence initialization of atomic variables is changed to also use
this API, instead of directly initializing the value.
This also fixes a few cases where atomic variables were
accessed directly.
see also libs/pbd/pbd/g_atomic_compat.h
By supporting FMA extension, the number of instruction needed
for multiply accumulate to mix channels are reduced. Since,
this extension has been around since middle of 2012, more
computers have this instruction set available.
This uses an atomic counter and spins only on the writer side, which
preserves realtime behavior on the reader side. The spinning yields (by
using the same Boost function from Boost spinlocks) to be
scheduler-friendly.
Fixing this bug also lets us be able to confidently drop garbage early
in the writer if appropriate, so do that and avoid keeping dead wood if
possible.
This reverts commit f95439a502:
"add spinlock to RCU manager to protect concurrent reader() and update() calls"
This is useful in cases where an object owns child objects
which in turn hold a reference to the parent.
In this case PluginInsert has-a Plugin, which may have a reference
to the insert or the Route.
On GLIBC systems pbd_stack_size() adds __pthread_get_minstack,
this is no available on mac systems, causing issues with some
libraries used by plugins.
This is a glibc-only extension, so don't bother on other platforms.
Also, according to POSIX, PTHREAD_STACK_MIN is defined in limits.h, so
include climits just to be safe.
Some libraries use thread locals and hence increase the min
requirement.
This is seen on void-linux for example:
> linking a minimal program against cairo gives a
> __static_tls_size of 43008 bytes.
> Doing the same on Ubuntu focal and Debian bullseye,
> __static_tls_size is only 4608.
The distance is between a given offset in the buffer (probably a
read position at some point in time) and the write ptr. Any data after
the write ptr is "old" and not readable, and thus not worth overwriting
since we would not read it anyway.
This is needed primarily for a workaround for #7971. When importing a template
that has been exported on Ardour5 on MacOS we need to fix the paths of the
archive entries.
Later we can use this functionality also to handle imported templates if
templates with the same name already exist.
This commit only adds methods and members to FileArchive, it does not modify
anything to make regressions unlikely. This, however, leads to some duplicated
code. Eventually we should consolidate this a bit.
These changes compile okay for me (using VS2019) although they wouldn't link to my older-built libraries. Hopefully he'll be okay if he builds everything with the same compiler.
gcc, and recent clang-10 can construct new objects
using references as arguments.
However clang-8 (and MSVC?) do not:
"error: no matching function for call to 'operator new'"
The compiler apparently does not expand the template
class A <-> `A*` vs. `A const&`
for different cases.
This is a dumb stack allocator using LIFO allocation/free, with
a fallback to new/delete. This works well for small STL containers
in particular std::vector, but it's also suitable for std::map<>,
in particular copy constructing small POD maps (plugin pin mappings).
Eventually this could be combined with TLSF for a flexible
memory arena management. This is however not currently needed
for any the planned use-cases.
This code is ANSI C++98 compatible, and yet also works with
modern C++11, C++14
~StatefulDiffCommand() may trigger UndoTransaction::command_death()
which may delete the StatefulDiffCommand() that's just being destroyed.
This depends on the signal-connection order, which is undefined.
In any case when a shared_ptr<> object is being destroyed it means
that all references to it are already gone. There's no need to
emit drop_references from the d'tor.
This fixes a case when deleting a plugin, deletes all automation
undo/redo events:
<UndoTransaction name="add automation event">
<MementoCommand type-name="ARDOUR::AutomationList">
...
`delete this;` calls the d'tor which emits drop_references(),
that leads to UndoTransaction::command_death() destroying the
object, whichh causes a double free.
When a playlist is deleted and drops_references(), any
undo/redo StatefulDiffCommand referncing playlist invoke
Destructible::drop_references() of the Command.
This leads to command_death(). As opposed to UndoTransaction::clear()
the StatefulDiffCommand was not destroyed.
In case of playlists StatefulDiffCommand::_changes contains
PBD::SequenceProperty<std::list<boost::shared_ptr<Region> > >
and shared pointer reference of the playlist regions were kept
indefinitely.
This fixes the following scenario:
New session, import an file, delete the created track,
clean up unused sources (delete unused playlists)[, quit].
A reference to the imported region was kept, because of the
playlist's undo command (insert region). Yet the source file
was deleted.
PS. Most playlist changes are accompanied by GUI zoom/selection
MementoCommands. Those are currently never directly dropped.
command_death() leaves those in place.
This fixes an issue when copy/pasting plugins or aux-sends from
one track to another. After copying the processor, the state
is copied, however the Controllable state did save
the InlineControl flag, so this as lost.
(amend 93180ceea)
PBD::IgnorableControllable() is no longer used.
It also was problematic, because in every case where a
Controllable is required, min/max range and usually also
get/set value are significant.
the value is used by the parser context; the old code called it only after the *first* parser context
was created. therefore the first XMLTree::read() call has its behavior determined by libxml2's default
for this value, rather than by our explicit choice (do not treat whitespace as a note). All subequent
read() calls will use our value.
This variable inside libxml2 is actually per-thread, which just increases the stakes for calling
xmlKeepBlanksDefault() at the right time
This is similar to sort(1) --human-numeric-sort,
as opposed to naturally_less() negative numbers, hex-prefixes
and SI metric prefixes are taken into account.
This allows to indicate that a control should by default be displayed
inline in the mixer-strip.
Previously that was hard-coded for and enabled for send-level
controls only.
It's long been a guideline (and IIRC a Weff-c++ warning) that either all, or
none, of the copy methods should be defined, but this became a standard warning
in GCC9. Presumably to account for a later language change though I'm not sure
which.
I don't remember why the ChanMapping copy constructor can't just be a simple
copy (it's just a map of POD), but figure it's safer to just copy what that
does.
103ef2ba08 introduced an API to write raw data (const void*)
to a child process, along with the previous API to
write (std::string const&)
VideoMonitor uses write_to_stdin("fixed text"), and g++
interprets this to use the (const void*) API instead
of the std::string, which breaks communication.
It's a well established convention that pan y-axis automation,
or vertical uses (top) +1 for left.
This special cases rotary knobs (and horizontal sliders) to retain
a clockwise movement (or movement to the right) for panning to the
right.
There are still over a hundred left, but this addresses many already.
In particular @param references to undocumented parameters.
Most notably in audio_backend.h
This works around for compilers with non-static-data-member
initialization.
spinlock_t is-a struct { lockType _; } and BOOST_DETAIL_SPINLOCK_INIT
initializes the first member of the struct.
All defines of BOOST_DETAIL_SPINLOCK_INIT include c-style curly braces
to initialize the struct's data member.
However, modern C++ compiler interpret the braces differently resulting
in copy constriction of the initializer.
Depending on implementation, d8ae3fd may only construct the spinlock
once to `sl_init`. Later it is only copy-constructed and that leads to
compile and/or runtmime errors.
e.g. gcc-8.3 fails to compile
error: use of deleted function ‘boost::detail::spinlock::spinlock(const boost::detail::spinlock&)’
To facilitate a central registry with weak/shared pointer lookup,
enable_shared_from_this<ARDOUR::AutomationControl>
was migrated to
enable_shared_from_this<PBD::Controllable>
The main (and only) user is generic-midi surface's state interface :(
This fixes a bug on some modern mac systems. Related to
setup_logging() changing stderr to use ASL and write to com.apple.console.
When a forked application writes to stderr while ASL is used,
the child is terminated for some reason.
Keep track of safe reservation:
Data has been read (or was skipped) previously can be read again
up to the allocated "reservation" (which is never overwritten).
This is mainly a NO-OP, introducing a new PlaybackBuffer type
and preparing for its use.
At this point in time, the buffer is just a power-of-two sized
ringbuffer and the disk-reader's read-logic is still unchanged.
Eventually the read and write sample position that are currently
private to the disk-reader can be migrated to be owned by the buffer.
Also Diskreader::read() positions can be matched to read-position ..
+/- buffer reservation and de-click can read w/o committing the read.
This is mostly to see if there'll be any problems when merging these changes into Mixbus. I'm guessing there'll be some conflicts in these projects (and a lot more to follow...)
Generated by tools/f2s. Some hand-editing will be required in a few places to fix up comments related to timecode
and video in order to keep the legible