@@ -869,6 +869,7 @@ const int esock_ioctl_flags_length = NUM(esock_ioctl_flags);
869869#define ESOCK_OPT_OTP_META 1009
870870#define ESOCK_OPT_OTP_USE_REGISTRY 1010
871871#define ESOCK_OPT_OTP_SELECT_READ 1011
872+ #define ESOCK_OPT_OTP_SCHEDULER_POLLING 1012
872873/**/
873874#define ESOCK_OPT_OTP_DOMAIN 1999 // INTERNAL AND ONLY GET
874875#if 0
@@ -1243,6 +1244,7 @@ static ERL_NIF_TERM esock_setopt_otp(ErlNifEnv* env,
12431244 ESOCK_SETOPT_OTP_FUNC_DEF(iow); \
12441245 ESOCK_SETOPT_OTP_FUNC_DEF(ctrl_proc); \
12451246 ESOCK_SETOPT_OTP_FUNC_DEF(select_read); \
1247+ ESOCK_SETOPT_OTP_FUNC_DEF(scheduler_polling); \
12461248 ESOCK_SETOPT_OTP_FUNC_DEF(rcvbuf); \
12471249 ESOCK_SETOPT_OTP_FUNC_DEF(rcvctrlbuf); \
12481250 ESOCK_SETOPT_OTP_FUNC_DEF(sndctrlbuf); \
@@ -1278,6 +1280,7 @@ static ERL_NIF_TERM esock_getopt_otp(ErlNifEnv* env,
12781280 ESOCK_GETOPT_OTP_FUNC_DEF(iow); \
12791281 ESOCK_GETOPT_OTP_FUNC_DEF(ctrl_proc); \
12801282 ESOCK_GETOPT_OTP_FUNC_DEF(select_read); \
1283+ ESOCK_GETOPT_OTP_FUNC_DEF(scheduler_polling); \
12811284 ESOCK_GETOPT_OTP_FUNC_DEF(rcvbuf); \
12821285 ESOCK_GETOPT_OTP_FUNC_DEF(rcvctrlbuf); \
12831286 ESOCK_GETOPT_OTP_FUNC_DEF(sndctrlbuf); \
@@ -6792,6 +6795,12 @@ ERL_NIF_TERM esock_setopt_otp(ErlNifEnv* env,
67926795 MUNLOCK (descP -> readMtx );
67936796 break ;
67946797
6798+ case ESOCK_OPT_OTP_SCHEDULER_POLLING :
6799+ MLOCK (descP -> readMtx );
6800+ result = esock_setopt_otp_scheduler_polling (env , descP , eVal );
6801+ MUNLOCK (descP -> readMtx );
6802+ break ;
6803+
67956804 case ESOCK_OPT_OTP_RCVBUF :
67966805 MLOCK (descP -> readMtx );
67976806 result = esock_setopt_otp_rcvbuf (env , descP , eVal );
@@ -6929,6 +6938,51 @@ ERL_NIF_TERM esock_setopt_otp_select_read(ErlNifEnv* env,
69296938
69306939
69316940
6941+ /* esock_setopt_otp_scheduler_polling - Handle the OTP (level) scheduler_polling option
6942+ */
6943+
6944+ static
6945+ ERL_NIF_TERM esock_setopt_otp_scheduler_polling (ErlNifEnv * env ,
6946+ ESockDescriptor * descP ,
6947+ ERL_NIF_TERM eVal )
6948+ {
6949+ BOOLEAN_T schedulerPolling ;
6950+
6951+ if (! IS_OPEN (descP -> readState )) {
6952+ SSDBG ( descP ,
6953+ ("SOCKET" , "esock_setopt_otp_scheduler_polling {%d} -> closed\r\n" ,
6954+ descP -> sock ) );
6955+ return esock_make_error_closed (env );
6956+ }
6957+
6958+ if (! esock_decode_bool (eVal , & schedulerPolling ))
6959+ return esock_make_invalid (env , esock_atom_value );
6960+
6961+ /* Check if scheduler polling is supported on this platform */
6962+ {
6963+ ErlNifSysInfo si ;
6964+ enif_system_info (& si , sizeof (ErlNifSysInfo ));
6965+ if (!si .scheduler_polling_support && schedulerPolling ) {
6966+ SSDBG ( descP ,
6967+ ("SOCKET" , "esock_setopt_otp_scheduler_polling {%d} -> notsup"
6968+ "\r\n scheduler polling not available on this platform"
6969+ "\r\n" , descP -> sock ) );
6970+ return esock_make_error (env , esock_atom_enotsup );
6971+ }
6972+ }
6973+
6974+ descP -> schedulerPolling = schedulerPolling ;
6975+
6976+ SSDBG ( descP ,
6977+ ("SOCKET" , "esock_setopt_otp_scheduler_polling {%d} -> ok"
6978+ "\r\n eVal: %T"
6979+ "\r\n" , descP -> sock , eVal ) );
6980+
6981+ return esock_atom_ok ;
6982+ }
6983+
6984+
6985+
69326986/* esock_setopt_otp_ctrl_proc - Handle the OTP (level)
69336987 * controlling_process options
69346988 */
@@ -8589,6 +8643,12 @@ ERL_NIF_TERM esock_getopt_otp(ErlNifEnv* env,
85898643 MUNLOCK (descP -> readMtx );
85908644 break ;
85918645
8646+ case ESOCK_OPT_OTP_SCHEDULER_POLLING :
8647+ MLOCK (descP -> readMtx );
8648+ result = esock_getopt_otp_scheduler_polling (env , descP );
8649+ MUNLOCK (descP -> readMtx );
8650+ break ;
8651+
85928652 case ESOCK_OPT_OTP_RCVBUF :
85938653 MLOCK (descP -> readMtx );
85948654 result = esock_getopt_otp_rcvbuf (env , descP );
@@ -8751,6 +8811,34 @@ ERL_NIF_TERM esock_getopt_otp_select_read(ErlNifEnv* env,
87518811
87528812
87538813
8814+ /* esock_getopt_otp_scheduler_polling - Handle the OTP (level) scheduler_polling option
8815+ */
8816+
8817+ static
8818+ ERL_NIF_TERM esock_getopt_otp_scheduler_polling (ErlNifEnv * env ,
8819+ ESockDescriptor * descP )
8820+ {
8821+ ERL_NIF_TERM eVal ;
8822+
8823+ if (! IS_OPEN (descP -> readState )) {
8824+ SSDBG ( descP ,
8825+ ("SOCKET" , "esock_getopt_otp_scheduler_polling {%d} -> done closed\r\n" ,
8826+ descP -> sock ) );
8827+ return esock_make_error_closed (env );
8828+ }
8829+
8830+ eVal = esock_encode_bool (descP -> schedulerPolling );
8831+
8832+ SSDBG ( descP ,
8833+ ("SOCKET" , "esock_getopt_otp_scheduler_polling {%d} ->"
8834+ "\r\n eVal: %T"
8835+ "\r\n" , descP -> sock , eVal ) );
8836+
8837+ return esock_make_ok2 (env , eVal );
8838+ }
8839+
8840+
8841+
87548842/* esock_getopt_otp_ctrl_proc - Handle the OTP (level) controlling_process option
87558843 */
87568844
@@ -12057,6 +12145,12 @@ ESockDescriptor* esock_alloc_descriptor(SOCKET sock)
1205712145 descP -> iow = FALSE;
1205812146 descP -> dbg = ESOCK_DEBUG_DEFAULT ; // Overwritten by caller
1205912147 descP -> selectRead = FALSE;
12148+ {
12149+ /* Query scheduler polling support at runtime */
12150+ ErlNifSysInfo si ;
12151+ enif_system_info (& si , sizeof (ErlNifSysInfo ));
12152+ descP -> schedulerPolling = si .scheduler_polling_support ? TRUE : FALSE;
12153+ }
1206012154 descP -> useReg = ESOCK_USE_SOCKET_REGISTRY ;// Overwritten by caller
1206112155 descP -> meta .env = esock_alloc_env ("esock_alloc_descriptor - "
1206212156 "meta-env" );
@@ -12692,9 +12786,15 @@ int esock_select_read(ErlNifEnv* env,
1269212786 ERL_NIF_TERM sockRef , // Socket
1269312787 ERL_NIF_TERM selectRef ) // "ID" of the operation
1269412788{
12789+ ESockDescriptor * descP = (ESockDescriptor * ) obj ;
1269512790 ERL_NIF_TERM selectMsg = mk_select_msg (env , sockRef , selectRef );
12791+ enum ErlNifSelectFlags flags = ERL_NIF_SELECT_READ | ERL_NIF_SELECT_CUSTOM_MSG ;
12792+
12793+ if (!descP -> schedulerPolling ) {
12794+ flags |= ERL_NIF_SELECT_NO_SCHEDULER_POLLSET ;
12795+ }
1269612796
12697- return enif_select_read (env , event , obj , pidP , selectMsg , NULL );
12797+ return enif_select_x (env , event , flags , obj , pidP , selectMsg , NULL );
1269812798
1269912799}
1270012800#endif // #ifndef __WIN32__
@@ -12716,9 +12816,15 @@ int esock_select_write(ErlNifEnv* env,
1271612816 ERL_NIF_TERM sockRef , // Socket
1271712817 ERL_NIF_TERM selectRef ) // "ID" of the operation
1271812818{
12819+ ESockDescriptor * descP = (ESockDescriptor * ) obj ;
1271912820 ERL_NIF_TERM selectMsg = mk_select_msg (env , sockRef , selectRef );
12821+ enum ErlNifSelectFlags flags = ERL_NIF_SELECT_WRITE | ERL_NIF_SELECT_CUSTOM_MSG ;
12822+
12823+ if (!descP -> schedulerPolling ) {
12824+ flags |= ERL_NIF_SELECT_NO_SCHEDULER_POLLSET ;
12825+ }
1272012826
12721- return enif_select_write (env , event , obj , pidP , selectMsg , NULL );
12827+ return enif_select_x (env , event , flags , obj , pidP , selectMsg , NULL );
1272212828}
1272312829#endif // #ifndef __WIN32__
1272412830
0 commit comments