Skip to content

Commit 6ff44b7

Browse files
Copilotderselbst
andauthored
Remove systemd lock-file gating and add automatic shell port selection (#1763)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: derselbst <8152480+derselbst@users.noreply.github.com> Co-authored-by: derselbst <tom.mbrt@googlemail.com>
1 parent c9a29f6 commit 6ff44b7

13 files changed

Lines changed: 150 additions & 27 deletions

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,5 @@ install_manifest.txt
4242
*.pro.user*
4343
*.user
4444
*.vscode
45+
_codeql_build_dir/
46+
_codeql_detected_source_root

CMakeLists.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -974,9 +974,6 @@ if ( UNIX )
974974
configure_file ( fluidsynth.service.in
975975
${FluidSynth_BINARY_DIR}/fluidsynth.service @ONLY )
976976

977-
configure_file ( fluidsynth.tmpfiles.in
978-
${FluidSynth_BINARY_DIR}/fluidsynth.tmpfiles @ONLY )
979-
980977
configure_file ( fluidsynth.conf.in
981978
${FluidSynth_BINARY_DIR}/fluidsynth.conf @ONLY )
982979

contrib/fluidsynth.spec

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ This package contains the shared library for Fluidsynth.
9797
# manually install systemd files
9898
install -Dm 644 build/fluidsynth.conf %{buildroot}%{_fillupdir}/sysconfig.%{name}
9999
install -Dm 644 build/fluidsynth.service %{buildroot}%{_unitdir}/%{name}.service
100-
install -Dm 644 build/fluidsynth.tmpfiles %{buildroot}%{_tmpfilesdir}/%{name}.conf
101100
install -d %{buildroot}%{_sbindir}
102101
ln -s %{_sbindir}/service %{buildroot}%{_sbindir}/rc%{name}
103102

@@ -128,7 +127,6 @@ ln -s %{_sbindir}/service %{buildroot}%{_sbindir}/rc%{name}
128127
%{_unitdir}/%{name}.service
129128
%{_sbindir}/rc%{name}
130129
%{_fillupdir}/sysconfig.%{name}
131-
%{_tmpfilesdir}/%{name}.conf
132130
%endif
133131

134132
%files devel

doc/fluidsettings.xml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -888,11 +888,10 @@ Developers:
888888
<setting>
889889
<name>port</name>
890890
<type>int</type>
891-
<def>9800</def>
892-
<min>1</min>
891+
<def>0</def>
892+
<min>0</min>
893893
<max>65535</max>
894-
<desc>The shell can be used in a client/server mode. This setting controls what TCP/IP port the server uses.</desc>
894+
<desc>The shell can be used in a client/server mode. This setting controls what TCP/IP port the server uses. Since fluidsynth 2.5.4, a value of 0 enables auto mode and selects the first free port, probing from 9800 upwards. Older versions used 9800 as default port. Note that when set to 0, fluidsynth will update the setting during server creation (new_fluid_server2()) with the actual port number used.</desc>
895895
</setting>
896896
</shell>
897897
</fluidsettings>
898-

doc/recent_changes.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
/*!
22

33
\page RecentChanges Recent Changes
4+
\section NewIn2_5_4 What's new in 2.5.4?
5+
- By default, fluidsynth now auto selects the TCP port for the shell server, see \setting{shell_port}
6+
47
\section NewIn2_5_0 What's new in 2.5.0?
58
- #FLUID_MOD_SIN is now deprecated, use the newly added fluid_mod_set_custom_mapping()
69
- A new mode for the custom IIR filter has been added: #FLUID_IIR_BEANLAND

fluidsynth.service.in

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ Documentation=man:fluidsynth(1)
44
After=sound.target
55
After=pipewire.service pulseaudio.service
66
Wants=pipewire.service pulseaudio.service
7-
# If you need more than one instance, use `systemctl edit` to override this:
8-
ConditionPathExists=!/run/lock/fluidsynth/fluidsynth.lock
97
ConditionUser=!@system
108

119
[Service]
@@ -27,9 +25,6 @@ Environment=OTHER_OPTS= SOUND_FONT=
2725
EnvironmentFile=@FLUID_DAEMON_ENV_FILE@
2826
EnvironmentFile=-%h/.config/fluidsynth
2927
ExecStart=@CMAKE_INSTALL_FULL_BINDIR@/fluidsynth -is $OTHER_OPTS "${SOUND_FONT}"
30-
ExecStartPre=touch /run/lock/fluidsynth/fluidsynth.lock
31-
ExecStopPost=rm -f /run/lock/fluidsynth/fluidsynth.lock
3228

3329
[Install]
3430
WantedBy=default.target
35-

fluidsynth.tmpfiles.in

Lines changed: 0 additions & 1 deletion
This file was deleted.

include/fluidsynth/shell.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,10 @@ FLUIDSYNTH_API void delete_fluid_shell(fluid_shell_t *shell);
114114
*
115115
* TCP socket server for a command handler.
116116
*
117-
* The socket server will open the TCP port set by \ref settings_shell_port
118-
* (default 9800) and starts a new thread and \ref command_handler for each
119-
* incoming connection.
117+
* The socket server will open the TCP port set by \ref settings_shell_port
118+
* (default 9800). If the setting is 0, the first free port is selected
119+
* automatically, probing from 9800 upwards. The server starts a new thread and
120+
* \ref command_handler for each incoming connection.
120121
*
121122
* @note The server is only available if libfluidsynth has been compiled
122123
* with network support (enable-network). Without network support, all related

src/bindings/fluid_cmd.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ static int fluid_handle_voice_count(void *data, int ac, char **av,
6767
void fluid_shell_settings(fluid_settings_t *settings)
6868
{
6969
fluid_settings_register_str(settings, "shell.prompt", "", 0);
70-
fluid_settings_register_int(settings, "shell.port", 9800, 1, 65535, 0);
70+
fluid_settings_register_int(settings, "shell.port", 0, 0, 65535, 0);
7171
}
7272

7373

@@ -4482,6 +4482,17 @@ new_fluid_server2(fluid_settings_t *settings,
44824482
return NULL;
44834483
}
44844484

4485+
if(port == 0)
4486+
{
4487+
int selected_port = fluid_server_socket_get_port(server->socket);
4488+
4489+
if(selected_port != FLUID_FAILED)
4490+
{
4491+
fluid_settings_setint(settings, "shell.port", selected_port);
4492+
FLUID_LOG(FLUID_INFO, "shell.port=0, using automatically selected port %d", selected_port);
4493+
}
4494+
}
4495+
44854496
return server;
44864497
#else
44874498
FLUID_LOG(FLUID_WARN, "Network support disabled on this platform.");

src/utils/fluid_sys.c

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ struct _fluid_timer_t
7070
struct _fluid_server_socket_t
7171
{
7272
fluid_socket_t socket;
73+
int port;
7374
fluid_thread_t *thread;
7475
int cont;
7576
fluid_server_func_t func;
@@ -1333,6 +1334,12 @@ int fluid_server_socket_join(fluid_server_socket_t *server_socket)
13331334
return fluid_thread_join(server_socket->thread);
13341335
}
13351336

1337+
int fluid_server_socket_get_port(fluid_server_socket_t *server_socket)
1338+
{
1339+
fluid_return_val_if_fail(server_socket != NULL, FLUID_FAILED);
1340+
return server_socket->port;
1341+
}
1342+
13361343
static int fluid_socket_init(void)
13371344
{
13381345
#ifdef _WIN32
@@ -1380,10 +1387,13 @@ void fluid_socket_close(fluid_socket_t sock)
13801387
{
13811388
if(sock != INVALID_SOCKET)
13821389
{
1390+
/* Trigger any pending blocking I/O (e.g. accept()) before closing. */
13831391
#ifdef _WIN32
1392+
shutdown(sock, SD_BOTH);
13841393
closesocket(sock);
13851394

13861395
#else
1396+
shutdown(sock, SHUT_RDWR);
13871397
close(sock);
13881398
#endif
13891399
}
@@ -1469,6 +1479,9 @@ new_fluid_server_socket(int port, fluid_server_func_t func, void *data)
14691479
const struct sockaddr *addr;
14701480
size_t addr_size;
14711481
fluid_socket_t sock;
1482+
int current_port = port;
1483+
int auto_port = (port == 0);
1484+
int bind_error;
14721485

14731486
fluid_return_val_if_fail(func != NULL, NULL);
14741487

@@ -1479,16 +1492,19 @@ new_fluid_server_socket(int port, fluid_server_func_t func, void *data)
14791492

14801493
FLUID_MEMSET(&addr4, 0, sizeof(addr4));
14811494
addr4.sin_family = AF_INET;
1482-
addr4.sin_port = htons((uint16_t)port);
14831495
addr4.sin_addr.s_addr = htonl(INADDR_ANY);
14841496

14851497
#ifdef IPV6_SUPPORT
14861498
FLUID_MEMSET(&addr6, 0, sizeof(addr6));
14871499
addr6.sin6_family = AF_INET6;
1488-
addr6.sin6_port = htons((uint16_t)port);
14891500
addr6.sin6_addr = in6addr_any;
14901501
#endif
14911502

1503+
if(auto_port)
1504+
{
1505+
current_port = FLUID_SHELL_AUTO_PORT_START;
1506+
}
1507+
14921508
#ifdef IPV6_SUPPORT
14931509
sock = socket(AF_INET6, SOCK_STREAM, 0);
14941510
addr = (const struct sockaddr *) &addr6;
@@ -1516,12 +1532,49 @@ new_fluid_server_socket(int port, fluid_server_func_t func, void *data)
15161532
return NULL;
15171533
}
15181534

1519-
if(bind(sock, addr, (int) addr_size) == SOCKET_ERROR)
1535+
while(1)
15201536
{
1521-
FLUID_LOG(FLUID_ERR, "Got error %d while trying to bind server socket", fluid_socket_get_error());
1522-
fluid_socket_close(sock);
1523-
fluid_socket_cleanup();
1524-
return NULL;
1537+
addr4.sin_port = htons((uint16_t) current_port);
1538+
#ifdef IPV6_SUPPORT
1539+
addr6.sin6_port = htons((uint16_t) current_port);
1540+
#endif
1541+
if(bind(sock, addr, (int) addr_size) == 0)
1542+
{
1543+
break;
1544+
}
1545+
1546+
bind_error = fluid_socket_get_error();
1547+
1548+
if(!auto_port)
1549+
{
1550+
FLUID_LOG(FLUID_ERR, "Got error %d while trying to bind server socket", bind_error);
1551+
fluid_socket_close(sock);
1552+
fluid_socket_cleanup();
1553+
return NULL;
1554+
}
1555+
1556+
#if defined(_WIN32)
1557+
if(bind_error != WSAEADDRINUSE)
1558+
#else
1559+
if(bind_error != EADDRINUSE)
1560+
#endif
1561+
{
1562+
FLUID_LOG(FLUID_ERR, "Got error %d while trying to bind server socket", bind_error);
1563+
fluid_socket_close(sock);
1564+
fluid_socket_cleanup();
1565+
return NULL;
1566+
}
1567+
1568+
if(current_port == FLUID_TCP_PORT_MAX)
1569+
{
1570+
FLUID_LOG(FLUID_ERR, "No free TCP port available for shell server auto mode (starting at %d)",
1571+
FLUID_SHELL_AUTO_PORT_START);
1572+
fluid_socket_close(sock);
1573+
fluid_socket_cleanup();
1574+
return NULL;
1575+
}
1576+
1577+
current_port++;
15251578
}
15261579

15271580
if(listen(sock, SOMAXCONN) == SOCKET_ERROR)
@@ -1543,6 +1596,7 @@ new_fluid_server_socket(int port, fluid_server_func_t func, void *data)
15431596
}
15441597

15451598
server_socket->socket = sock;
1599+
server_socket->port = current_port;
15461600
server_socket->func = func;
15471601
server_socket->data = data;
15481602
server_socket->cont = 1;

0 commit comments

Comments
 (0)