There's a report about a nightly "crash" when users download, compile
from source, and replace their distro's mindlnad binary. This is because
the Debian package includes a patch that uses SIGUSR2 to reopen the log
file and sends SIGUSR2 from logrotate instead of just using the
"copytruncate" logrotate option. Then logrotate sends SIGUSR2 at 6:25AM,
which causes us to abort due to the unhandled signal.
I don't want to sacrifice SIGUSR2 just for log rotation, especially when
we already do some reload operations on SIGHUP. So to avoid this
Debian/Ubuntu issue, we'll explicitly ignore SIGUSR2, and add log file
reopening to the SIGHUP handler. Then hopefully a future Debian package
version will remove the SIGUSR2 patch and use SIGHUP instead (or
copytruncate).
Fixes: SF Bug #313 (log rotation kills minidlna service)
Some effort was made to unify monitoring via kqueue and via inotify
APIs. Now both provide their implementation of add_watch() function.
I guess there are some logical bugs in vnode_process(). With this commit
it would be better provide code as is, and resolve bugs separately.
The idea is taken from the nginx web server, but much simplified and
almost no copypaste left. This will allow minidlna to use different
event dispatcher APIs, which would be defined at compile time.
My personal goal is to convert minidlna to kqueue(2) on FreeBSD. This
would later allow for kqueue based directory change notification, which
won't conflict with select(2) like the current patch does.
Other platforms will also benefit from the pluggability of the event
system, Linux can switch to epoll(2) or at least to poll(2).
Detailed list of changes:
* event.h [New]
Our internal API to unify different event dispatch systems.
* select.c [New]
Much simplified version of nginx's ngx_select_module.c.
* minidlna.c
- Split out listen socket event processing into separate function
ProcessListen(), which matches event_process_t type.
- Create and initialize struct event for the monitor socket, SSDP
socket, HTTP socket and beacon socket.
- Simplify and make more precise timeout calculation using
helper timeval functions from utils.c. Treat gettimeofday() error
as a fatal event.
- Rip out all stuff related to select(2). Just call event_module.process().
* upnpevents.c
- Embed struct event into upnp_event_notify.
- Merge upnp_event_create_notify() with upnp_event_notify_connect().
Start connecting immediately after socket creation. Garbage collect
now useless ECreated state.
- Make upnp_event_process_notify() of event_process_t type, and use it
as process callback for upnp_event_notify event.
- Looks like we always create upnp_event_notify with existing subscriber,
and never clear it later. Remove checks for obj->sub and assert that it
is never NULL. Simplifies things.
- When switching obj state, add/del it to event dispatcher accrodingly.
- Garbage collect upnpevents_selectfds().
- Garbage collect select(2) related stuff from upnpevents_processfds().
Rename function to upnpevents_gc(), since the remaining functionality
is garbage collecting, not file descriptor processing.
Actually, this can be simplified even more. We can safely close sockets
and free objects immediately, eliminating need for upnpevents_gc(). But
this change would be beyond scope of this commit.
* upnphttp.c, upnphttp.h
Embed struct event into struct upnphttp. Adjust Process_upnphttp() to match
event_process_t type. Add/del to event dispatcher once creating/closing a
socket.
* minissdp.c, minissdp.h
Make ProcessSSDPRequest() of event_process_t type.
* getifaddr.c, getifaddr.h
Make ProcessMonitorEvent() of event_process_t type.
Add the ability to force title modification for clients that do their own
alphanumeric sorting. Adding a '!' to the beginning of the
force_sort_criteria value will enable this behavior.
It is implemented by prepending all titles with a zero-padded number, and
possibly season and episode (or disc and track) numbers if they aren't
already in the title.
Fix several issues with the non-destructive rescan functionality.
Most of these issues also affected inotify scanning as well. These
include annoying debug messages, adding album art for files that we
aren't supposed to be scanning anyway, incrementing the UpdateID when no
changes were made to the database, and other smaller issues.
Add support for upnp:playbackCount and upnp:lastPlaybackPosition tags.
These are used by Kodi to keep track of bookmark information as well as
determining whether to show the checkmark to indicate that the video
has been played.
Also add support for the UpdateObject command, which Kodi uses to
update the playbackCount and lastPlaybackPosition information.
This change requires a DB schema update, which should be done
automatically on the first run.
Inspired by SF user Karsten's patch #167.
We shouldn't blindly set the LC_CTYPE to en_US.utf8, because the user may
not have it installed. So if the user already has a utf8 locale defined,
just use it for LC_CTYPE.
Fixed: SF Bug #87 (Problem of accentuation)
SubmitServicesToMiniSSDPD(lan_addr[0].str, runtime_vars.port)
is called before lan_addr[0].str get a proper value.
Patch add call to reload_ifaces() in order to fix that
see miniupnp forum post http://miniupnp.tuxfamily.org/forum/viewtopic.php?t=1801
Thanks Thomas Bernard for this fix.
By default, if there are multiple media directories specified, there
will be entries for each one in the root directory container. If
there is only one media directory specified, then just its contents
will be in the root container, to save one level of browsing.
Setting this option changes the default behavior so that multiple
media dirs will behave like a single media dir.
At least some Panasonic clients try to open more than 5 simultaneous
connections to the server. If we keep the default of 5 max children,
it results in choppy playback on those clients.
Make this setting configurable, and default to 50 max connections.
Our process is pretty lightweight, so 50 children should not be a
problem on most systems.
If an interface comes online after startup, we really need to send a
complete byebye + alive set on that interface, but we don't want to do
it for other interfaces. So do it as the interfaces come up, and
skip it for interfaces that existed before the reload.