@@ -182,7 +182,12 @@ struct discord_rpc
182182/* File-scope globals (replaces upstream's scattered static storage) */
183183/* ------------------------------------------------------------------------ */
184184
185- static struct discord_rpc discord_rpc_inst ;
185+ /* The rpc instance, presence slot and send queue together are over
186+ * 200 kilobytes of buffers; heap-allocated at discord_init so a
187+ * session that never enables rich presence never pays for them.
188+ * Load-resident statics are never free on platforms without demand
189+ * paging. */
190+ static struct discord_rpc * discord_rpc_inst ;
186191static bool discord_rpc_inst_valid = false;
187192
188193static int discord_pid = 0 ;
@@ -207,11 +212,11 @@ static bool discord_was_spectate_game = false;
207212
208213/* Pending presence update. Only the most recent one matters; we just keep one
209214 * slot and overwrite it. */
210- static struct discord_queued_msg discord_queued_presence ;
215+ static struct discord_queued_msg * discord_queued_presence ;
211216
212217/* Send queue (subscribe / unsubscribe / respond commands). Single-threaded, so
213218 * it is just a wraparound ring buffer with a pending counter. */
214- static struct discord_queued_msg discord_send_queue [ DISCORD_SEND_QUEUE_SIZE ] ;
219+ static struct discord_queued_msg * discord_send_queue ;
215220static unsigned discord_send_next_add = 0 ;
216221static unsigned discord_send_next_send = 0 ;
217222static unsigned discord_send_pending = 0 ;
@@ -876,23 +881,23 @@ static void discord_rpc_close(struct discord_rpc *rpc);
876881
877882static void discord_rpc_create (const char * application_id )
878883{
879- memset (& discord_rpc_inst , 0 , sizeof (discord_rpc_inst ));
884+ memset (discord_rpc_inst , 0 , sizeof (* discord_rpc_inst ));
880885#ifdef _WIN32
881- discord_rpc_inst . pipe = INVALID_HANDLE_VALUE ;
886+ discord_rpc_inst -> pipe = INVALID_HANDLE_VALUE ;
882887#else
883- discord_rpc_inst . sock = -1 ;
888+ discord_rpc_inst -> sock = -1 ;
884889#endif
885- discord_rpc_inst . state = DISCORD_STATE_DISCONNECTED ;
886- strlcpy (discord_rpc_inst . app_id , application_id ,
887- sizeof (discord_rpc_inst . app_id ));
890+ discord_rpc_inst -> state = DISCORD_STATE_DISCONNECTED ;
891+ strlcpy (discord_rpc_inst -> app_id , application_id ,
892+ sizeof (discord_rpc_inst -> app_id ));
888893 discord_rpc_inst_valid = true;
889894}
890895
891896static void discord_rpc_destroy (void )
892897{
893898 if (!discord_rpc_inst_valid )
894899 return ;
895- discord_rpc_close (& discord_rpc_inst );
900+ discord_rpc_close (discord_rpc_inst );
896901 discord_rpc_inst_valid = false;
897902}
898903
@@ -1135,6 +1140,8 @@ static void discord_rpc_open(struct discord_rpc *rpc)
11351140static struct discord_queued_msg * discord_send_queue_next_add (void )
11361141{
11371142 unsigned idx ;
1143+ if (!discord_send_queue )
1144+ return NULL ;
11381145 if (discord_send_pending >= DISCORD_SEND_QUEUE_SIZE )
11391146 return NULL ;
11401147 idx = (discord_send_next_add ++ ) % DISCORD_SEND_QUEUE_SIZE ;
@@ -1153,7 +1160,10 @@ static bool discord_send_queue_has_pending(void)
11531160
11541161static struct discord_queued_msg * discord_send_queue_next_send (void )
11551162{
1156- unsigned idx = (discord_send_next_send ++ ) % DISCORD_SEND_QUEUE_SIZE ;
1163+ unsigned idx ;
1164+ if (!discord_send_queue )
1165+ return NULL ;
1166+ idx = (discord_send_next_send ++ ) % DISCORD_SEND_QUEUE_SIZE ;
11571167 return & discord_send_queue [idx ];
11581168}
11591169
@@ -1300,12 +1310,12 @@ static void discord_update_connection(void)
13001310 if (!discord_rpc_inst_valid )
13011311 return ;
13021312
1303- if (!discord_rpc_is_open (& discord_rpc_inst ))
1313+ if (!discord_rpc_is_open (discord_rpc_inst ))
13041314 {
13051315 if (discord_now_ms () >= discord_next_connect_ms )
13061316 {
13071317 discord_next_connect_ms = discord_now_ms () + discord_backoff_next_delay ();
1308- discord_rpc_open (& discord_rpc_inst );
1318+ discord_rpc_open (discord_rpc_inst );
13091319 }
13101320 return ;
13111321 }
@@ -1314,7 +1324,7 @@ static void discord_update_connection(void)
13141324 for (;;)
13151325 {
13161326 char * json_buf = NULL ;
1317- rjson_t * r = discord_rpc_read (& discord_rpc_inst , & json_buf );
1327+ rjson_t * r = discord_rpc_read (discord_rpc_inst , & json_buf );
13181328 char * evt_name = NULL ;
13191329 char * nonce = NULL ;
13201330 char * secret = NULL ;
@@ -1426,25 +1436,25 @@ static void discord_update_connection(void)
14261436 }
14271437
14281438 /* Writes -------------------------------------------------------------- */
1429- if (discord_queued_presence . length )
1439+ if (discord_queued_presence -> length )
14301440 {
14311441 struct discord_queued_msg local ;
1432- local .length = discord_queued_presence . length ;
1433- memcpy (local .buffer , discord_queued_presence . buffer , local .length );
1434- discord_queued_presence . length = 0 ;
1442+ local .length = discord_queued_presence -> length ;
1443+ memcpy (local .buffer , discord_queued_presence -> buffer , local .length );
1444+ discord_queued_presence -> length = 0 ;
14351445
1436- if (!discord_rpc_write (& discord_rpc_inst , local .buffer , local .length ))
1446+ if (!discord_rpc_write (discord_rpc_inst , local .buffer , local .length ))
14371447 {
14381448 /* On failure, requeue for a later attempt. */
1439- discord_queued_presence . length = local .length ;
1440- memcpy (discord_queued_presence . buffer , local .buffer , local .length );
1449+ discord_queued_presence -> length = local .length ;
1450+ memcpy (discord_queued_presence -> buffer , local .buffer , local .length );
14411451 }
14421452 }
14431453
14441454 while (discord_send_queue_has_pending ())
14451455 {
14461456 struct discord_queued_msg * q = discord_send_queue_next_send ();
1447- discord_rpc_write (& discord_rpc_inst , q -> buffer , q -> length );
1457+ discord_rpc_write (discord_rpc_inst , q -> buffer , q -> length );
14481458 discord_send_queue_commit_send ();
14491459 }
14501460}
@@ -1478,6 +1488,8 @@ void Discord_Initialize(const char *application_id,
14781488{
14791489 (void )auto_register ;
14801490 (void )optional_steam_id ;
1491+ if (!discord_rpc_inst )
1492+ return ;
14811493
14821494 /* Seed the cheap backoff jitter once. */
14831495 srand ((unsigned )time (NULL ));
@@ -1497,6 +1509,18 @@ void Discord_Initialize(const char *application_id,
14971509 if (discord_rpc_inst_valid )
14981510 return ;
14991511
1512+ if (!discord_rpc_inst )
1513+ discord_rpc_inst = (struct discord_rpc * )
1514+ calloc (1 , sizeof (* discord_rpc_inst ));
1515+ if (!discord_queued_presence )
1516+ discord_queued_presence = (struct discord_queued_msg * )
1517+ calloc (1 , sizeof (* discord_queued_presence ));
1518+ if (!discord_send_queue )
1519+ discord_send_queue = (struct discord_queued_msg * )
1520+ calloc (DISCORD_SEND_QUEUE_SIZE , sizeof (* discord_send_queue ));
1521+ if (!discord_rpc_inst || !discord_queued_presence || !discord_send_queue )
1522+ return ;
1523+
15001524 discord_rpc_create (application_id );
15011525 discord_next_connect_ms = discord_now_ms ();
15021526}
@@ -1507,6 +1531,15 @@ void Discord_Shutdown(void)
15071531 return ;
15081532 memset (& discord_handlers , 0 , sizeof (discord_handlers ));
15091533 discord_rpc_destroy ();
1534+ if (discord_rpc_inst )
1535+ free (discord_rpc_inst );
1536+ if (discord_queued_presence )
1537+ free (discord_queued_presence );
1538+ if (discord_send_queue )
1539+ free (discord_send_queue );
1540+ discord_rpc_inst = NULL ;
1541+ discord_queued_presence = NULL ;
1542+ discord_send_queue = NULL ;
15101543}
15111544
15121545void Discord_UpdateConnection (void )
@@ -1516,9 +1549,11 @@ void Discord_UpdateConnection(void)
15161549
15171550void Discord_UpdatePresence (const DiscordRichPresence * presence )
15181551{
1519- discord_queued_presence .length = discord_json_write_rich_presence (
1520- discord_queued_presence .buffer ,
1521- sizeof (discord_queued_presence .buffer ),
1552+ if (!discord_queued_presence )
1553+ return ;
1554+ discord_queued_presence -> length = discord_json_write_rich_presence (
1555+ discord_queued_presence -> buffer ,
1556+ sizeof (discord_queued_presence -> buffer ),
15221557 discord_nonce ++ , discord_pid , presence );
15231558}
15241559
@@ -1531,7 +1566,7 @@ void Discord_Respond(const char *user_id, int reply)
15311566{
15321567 struct discord_queued_msg * q ;
15331568
1534- if (!discord_rpc_inst_valid || !discord_rpc_is_open (& discord_rpc_inst ))
1569+ if (!discord_rpc_inst_valid || !discord_rpc_is_open (discord_rpc_inst ))
15351570 return ;
15361571
15371572 q = discord_send_queue_next_add ();
@@ -1552,7 +1587,7 @@ void Discord_RunCallbacks(void)
15521587
15531588 was_disconnected = discord_was_just_disconnected ;
15541589 discord_was_just_disconnected = false;
1555- is_connected = discord_rpc_is_open (& discord_rpc_inst );
1590+ is_connected = discord_rpc_is_open (discord_rpc_inst );
15561591
15571592 /* If we are currently connected, fire the disconnect callback first so
15581593 * the outward-facing sequence is always ready -> ... -> disconnected. */
0 commit comments