diff --git a/pkgs/racket-doc/scribblings/reference/networking.scrbl b/pkgs/racket-doc/scribblings/reference/networking.scrbl index 184441361b..6f098fcaa0 100644 --- a/pkgs/racket-doc/scribblings/reference/networking.scrbl +++ b/pkgs/racket-doc/scribblings/reference/networking.scrbl @@ -498,14 +498,13 @@ exception is raised, but not both.} [size exact-positive-integer?]) void]{ -On Unix systems, set the receive buffer size (@tt{SO_RCVBUF}) for -@racket[udp-socket]. +Set the receive buffer size (@tt{SO_RCVBUF}) for @racket[udp-socket]. +Using a larger buffer can minimize packet loss that can occur due to +slow polling of a connection, including during a major garbage +collection. If @racket[size] is greater than the maximum allowed by the system, -the @exnraise[exn:fail]. - -Using a larger buffer can minimize packet loss that can occur during a -major garbage collection. +the @exnraise[exn:fail:network]. @history[#:added "7.1.0.11"]} diff --git a/pkgs/racket-test-core/tests/racket/udp.rktl b/pkgs/racket-test-core/tests/racket/udp.rktl index aedd85949d..9603db3895 100644 --- a/pkgs/racket-test-core/tests/racket/udp.rktl +++ b/pkgs/racket-test-core/tests/racket/udp.rktl @@ -57,12 +57,14 @@ (err/rt-test (udp-set-receive-buffer-size! udp1 -1)) (err/rt-test (udp-set-receive-buffer-size! udp1 0)) +(err/rt-test (udp-set-receive-buffer-size! udp1 (expt 2 300)) + exn:fail:network?) ;; Something a user program might do to find the max allowed size (test-values '(ok) (λ () (let loop ([n 4096]) - (with-handlers ([exn:fail? + (with-handlers ([exn:fail:network? (λ _ (let ([n (/ n 2)]) (udp-set-receive-buffer-size! udp1 n) diff --git a/racket/src/io/network/udp-receive.rkt b/racket/src/io/network/udp-receive.rkt index 5442b830ef..8a56d92a99 100644 --- a/racket/src/io/network/udp-receive.rkt +++ b/racket/src/io/network/udp-receive.rkt @@ -164,6 +164,9 @@ (check who exact-nonnegative-integer? size) (atomically (check-udp-closed who u) + (unless (fixnum? size) + (end-atomic) + (raise-non-fixnum who size)) (define r (rktio_udp_set_receive_buffer_size rktio (udp-s u) size)) (when (rktio-error? r) (raise-option-error who "set" r)))) @@ -171,3 +174,11 @@ (define (raise-option-error who mode v) (end-atomic) (raise-network-error who v (string-append mode "sockopt failed"))) + +(define (raise-non-fixnum who size) + (raise (exn:fail:network + (format (string-append "~a: given size is too large\n" + " given size: ~e") + who + size) + (current-continuation-marks)))) diff --git a/racket/src/racket/src/network.c b/racket/src/racket/src/network.c index 894c8a2f46..c7575dc0ec 100644 --- a/racket/src/racket/src/network.c +++ b/racket/src/racket/src/network.c @@ -2704,7 +2704,13 @@ static Scheme_Object *udp_set_receive_buffer_size(int argc, Scheme_Object *argv[ scheme_wrong_contract("udp-set-receive-buffer-size!", "udp?", 0, argc, argv); if (!SCHEME_INTP(argv[1]) || (SCHEME_INT_VAL(argv[1]) <= 0)) { - scheme_wrong_contract("udp-set-receive-buffer-size!", "exact-positive-integer?", 1, argc, argv); + if (SCHEME_BIGNUMP(argv[1]) && SCHEME_BIGPOS(argv[1])) + scheme_raise_exn(MZEXN_FAIL_NETWORK, + "udp-set-receive-buffer-size!: given size is too large\n" + " given size: %V", + argv[1]); + else + scheme_wrong_contract("udp-set-receive-buffer-size!", "exact-positive-integer?", 1, argc, argv); return NULL; }