Mindful that some autobuild packages populate only packages/lib/release
(rather than packages/lib/debug), Linking.cmake always appends
packages/lib/release to CMake's link_directories() directive. But since CMake
always appends CMAKE_BUILD_TYPE to those directories, we end up with a phantom
packages/lib/release/Release directory on the search path. This would be
harmless except that the Mac's 'ld' command produces a warning. These warnings
quickly make TC's "Important Messages" output useless. Try appending
packages/lib/release only when the build type isn't already Release.
This handles the case when the target file doesn't exist, just as APR_TRUNCATE
handles the case when it does.
Strengthen error checks concerning downloaded installer file from
ll_apr_warn_status() to ll_apr_assert_status(). Failing to recognize (e.g.)
failure to open that file only leads to mysterious crashes down the road; this
removes the mystery.
On Windows, calling CreateProcess(bInheritHandles=FALSE) is the wrong idea. In
that case, CreateProcess() passes NO handles -- even the files you've
explicitly designated as the child's stdin, stdout, stderr in the STARTUPINFO
struct! Remove LLProcess code to tweak bInheritHandles; we should also remove
the corresponding (useless) APR extension.
Instead, given that the Windows file-locking problem we've observed is
specific to the viewer installer .exe file downloaded by the background
updater logic, use APR file I/O for that specific file. Empirically, both
llofstream and std::ofstream seem to make the open file handle inheritable;
but apr_file_open() documentation says: "By default, the returned file
descriptor will not be inherited by child processes created by
apr_proc_create()." And indeed, it does appear to sidestep the locking problem.
That is, when the underlying LLError::Settings object is destroyed -- possibly
at termination, possibly on LLError::restoreSettings() -- the passed Recorder*
is deleted.
There was much existing code that seemed as unaware of this alarming fact as I
was myself. Passing to addRecorder() a pointer to a stack object, or to a
member of some other object, is just Bad. It might be preferable to make
addRecorder() accept std::auto_ptr<Recorder> to make the ownership transfer
more explicit -- or even boost::shared_ptr<Recorder> instead, which would
allow the caller to either forget or retain the passed Recorder.
This preliminary pass retains the Recorder* dumb pointer API, but documents
the ownership issue, and eliminates known instances of passing pointers to
anything but a standalone heap Recorder subclass object.
On Windows, Bad Things happen when apr_proc_create() is allowed to pass TRUE
to CreateProcess(bInheritHandles). For instance, the open handle for a new
installer executable file being downloaded by the background updater gets
inadvertently passed to a couple slplugin.exe instances. When the viewer
finishes downloading, closes the file and tries to remove it, Windows balks
because the file is still open by another process. Require an apr_suite
package that includes the new Linden apr_procattr_inherit_set() extension, and
call it to turn off CreateProcess(bInheritHandles).