@@ -3675,10 +3675,13 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx,
36753675#endif
36763676}
36773677
3678- #define ACTIVE_SESSION_MAGIC 0xDEFA1234U
3679- #define REMOVED_SESSION_MAGIC 0xDEADDEEDU
3678+ #define ACTIVE_SESSION_MAGIC 0xDEFA1234U
3679+ #define REMOVED_SESSION_MAGIC 0xDEADDEEDU
3680+ #define MIN_FREE_FDS 10
3681+ #define DESCRIPTORS_PER_SESSION 2
36803682
36813683static int nActiveSessions = 0 ;
3684+ static int maxActiveSessions = 0 ;
36823685
36833686static SessionContext *
36843687CreateSession (void )
@@ -3694,6 +3697,23 @@ CreateSession(void)
36943697 session -> magic = ACTIVE_SESSION_MAGIC ;
36953698 session -> eventPos = -1 ;
36963699 nActiveSessions += 1 ;
3700+ if (nActiveSessions > maxActiveSessions )
3701+ {
3702+ int new_max_safe_fds = max_safe_fds - (nActiveSessions - maxActiveSessions )* DESCRIPTORS_PER_SESSION ;
3703+ if (new_max_safe_fds >= MIN_FREE_FDS )
3704+ {
3705+ max_safe_fds = new_max_safe_fds ;
3706+ /* Ensure that we have enough free descriptors to establish new session.
3707+ * Unlike fd.c, which throws away lest recently used file descriptors
3708+ * only when open() call is failed, we prefer more conservative (pessimistic)
3709+ * aporach here.
3710+ */
3711+ ReleaseLruFiles ();
3712+ }
3713+ else
3714+ elog (WARNING , "Too few free file desriptors %d for %d sessions" , new_max_safe_fds , maxActiveSessions );
3715+ maxActiveSessions = nActiveSessions ;
3716+ }
36973717 return session ;
36983718}
36993719
@@ -3723,15 +3743,15 @@ SwitchToSession(SessionContext *session)
37233743 RestoreSessionGUCs (ActiveSession );
37243744 ActiveSession = session ;
37253745
3726- MyProcPort = ActiveSession -> port ;
3727- SetTempNamespaceState (ActiveSession -> tempNamespace ,
3728- ActiveSession -> tempToastNamespace );
3746+ MyProcPort = session -> port ;
3747+ SetTempNamespaceState (session -> tempNamespace ,
3748+ session -> tempToastNamespace );
37293749 pq_set_current_state (session -> port -> pqcomm_state , session -> port ,
37303750 session -> eventSet );
37313751 whereToSendOutput = DestRemote ;
37323752
3733- RestoreSessionGUCs (ActiveSession );
3734- LoadSessionVariables (ActiveSession );
3753+ RestoreSessionGUCs (session );
3754+ LoadSessionVariables (session );
37353755}
37363756
37373757static void
@@ -4369,11 +4389,12 @@ PostgresMain(int argc, char *argv[],
43694389 pgsocket sock ;
43704390 MemoryContext oldcontext ;
43714391
4392+ session = CreateSession ();
4393+
43724394 sock = pg_recv_sock (SessionPoolSock );
43734395 if (sock == PGINVALID_SOCKET )
43744396 elog (ERROR , "Failed to receive session socket: %m" );
43754397
4376- session = CreateSession ();
43774398
43784399 /* Initialize port and wait event set for this session */
43794400 oldcontext = MemoryContextSwitchTo (session -> memory );
@@ -4436,11 +4457,10 @@ PostgresMain(int argc, char *argv[],
44364457 pq_sendint (& buf , (int32 ) MyProcPid , 4 );
44374458 pq_sendint (& buf , (int32 ) MyCancelKey , 4 );
44384459 pq_endmessage (& buf );
4439-
44404460 /* Need not flush since ReadyForQuery will do it. */
4441- send_ready_for_query = true;
44424461
4443- continue ;
4462+ ReadyForQuery (whereToSendOutput );
4463+ goto ChooseSession ;
44444464 }
44454465 else
44464466 {
0 commit comments