These historically used atomics to manage their lifetime. They were
unfortunately unsafe and later replace with a RwLock. A lock is
also problematic as it is too heavy weight for the typical use case
and implies that logging is neither async nor fork safe.
This change returns us to using atomics with two key changes:
1) compare_exchange_strong() is used instead of atomic_exchange().
The latter has a race condition where a separate thread could have
read the atomic value into a register, while the thread performing
the atomic_exchange closes that FD. The new code only changes the
FD in the atomic if it is uninitialized.
2) Using the fact that DGRAM sockets can have connect() called on them
multiple times, it uses a single logd_socket for the duration of
the program.
These sockets are thread/async/fork safely created and accessed.
The one caveat is __android_log_close(), which is intended only to be
used by zygote when it is single threaded and is therefore not thread
safe. It will close this socket and reset the underlying variable,
such that the next log message will go through the above
initialization.
Bug: 65062446
Test: logging works, logging unit tests
Test: new unit test
Change-Id: Ia4dbf7479dbe50683d124558ab2f83bff53b8f5f
Cleanup the headers; we really don't want to encourage any more
cutils/list.h usage...
Remove __android_log_uid() since the only remaining users are built
for device, so they can just use getuid() directly.
Test: build
Change-Id: I62be2c1e43d83807deaa9342afcc72459947cf15
Remove the transport available and open functions since the writers
are able to manage their own state. Remove the initialization dance
with write_to_log, since it is unneeded once this is removed as well.
Remove the global lock around the close() functions as correct locking
has been added to the writers in a previous change.
Test: logging works, liblog-unit-tests
Change-Id: If7fa11e773763d0b5fcb2e696ad1c88ff4a4cfdf
The current system of using atomics isn't thread safe and may result
in doubly closing FDs or closing actively used FDs. The safest way to
do this is to use a rwlock, which should not have a much higher
overhead than the atomics do, as a vast majority of the time, there
will not be writers.
This moves us further away from using the transport interface, which
will be removed. Each writer should be self contained, without a
separate open or available function.
Also, keep the pmsg fd open if it is opened by
__android_log_pmsg_file_write(). This fd was closed due to issues
with zygote, but it looks like it is only called by recovery now, so
there is no reason to close this fd at the end of that function.
Test: logging works, liblog-unit-tests
Change-Id: I345c9a5d18c55b11a280c8362df854784abf46fd
This protocol documentation is spread out among various functions
where it is implemented. This change makes a single
README.protocol.md file with a high level overview, referencing the
struct names where useful.
Test: n/a
Change-Id: I83c9f484352b489b4a20cce241d92413f780f9ec
The "branchless" macro generates slightly worse code than std::min or
<sys/param.h>'s MIN.
Test: treehugger
Change-Id: I92c17325383bd6116c7b4736d42f01f7a9bb81a3
Now that we only have one transport in a given build configuration,
there is no need to have these lists.
Test: liblog-unit-tests
Change-Id: I3fdcdc33c1224a9522080ea06f36f14c83d946ac
readv() isn't used by anyone, writev() has one easily replaced user.
uio.h can be left as a private header for windows compatibility with
struct iovec.
Test: build
Change-Id: I33d4c6bdee6fd818271f78ae06abdd2aa09430f2