I've finally figured out why the master server thread segfaults if you start the game without an internet connection on OpenGL!
In D_RegisterServerCommands, the main thread registers cv_masterserver, which starts the change-masterserver thread. Then, the main thread calls D_RegisterClientCommands, which registers a series of 20 cvars (starting with cv_globalgamma), all of which call V_SetPalette when initialized. At the same time, the MS thread might fail and print an error to the console. If there's no connection, it fails immediately.
At this point, a conflict occurs as the MS thread tries drawing patches while the main thread is flushing the cache; the patch in use by the MS thread is suddenly freed, triggering the segfault.
My solution? Move those 20 cvars to SCR_Startup, which runs before D_RegisterServerCommands.
Also, while researching, I found and fixed a bug in HMS_set_rules which made it accidentally return its (uninitialized) buffer if HMS_do fails.
I've finally figured out why the master server thread segfaults if you start the game without an internet connection on OpenGL!
In
D_RegisterServerCommands
, the main thread registerscv_masterserver
, which starts thechange-masterserver
thread. Then, the main thread callsD_RegisterClientCommands
, which registers a series of 20 cvars (starting withcv_globalgamma
), all of which callV_SetPalette
when initialized. At the same time, the MS thread might fail and print an error to the console. If there's no connection, it fails immediately.At this point, a conflict occurs as the MS thread tries drawing patches while the main thread is flushing the cache; the patch in use by the MS thread is suddenly freed, triggering the segfault.
My solution? Move those 20 cvars to
SCR_Startup
, which runs beforeD_RegisterServerCommands
.Also, while researching, I found and fixed a bug in
HMS_set_rules
which made it accidentally return its (uninitialized) buffer ifHMS_do
fails.