{"size": 2512, "ext": "scrbl", "max_stars_repo_path": "pkgs/racket-doc/scribblings/foreign/try-atomic.scrbl", "max_stars_repo_name": "lkh01/racket", "max_stars_repo_stars_event_min_datetime": "2018-07-29T04:13:52.000Z", "max_stars_repo_stars_event_max_datetime": "2022-02-14T16:11:17.000Z", "max_issues_repo_path": "pkgs/racket-doc/scribblings/foreign/try-atomic.scrbl", "max_issues_repo_name": "lkh01/racket", "max_issues_repo_issues_event_min_datetime": "2017-08-25T20:26:37.000Z", "max_issues_repo_issues_event_max_datetime": "2022-02-26T17:48:40.000Z", "max_forks_repo_path": "pkgs/racket-doc/scribblings/foreign/try-atomic.scrbl", "max_forks_repo_name": "lkh01/racket", "max_forks_repo_forks_event_min_datetime": "2016-04-25T11:47:57.000Z", "max_forks_repo_forks_event_max_datetime": "2017-05-09T14:52:48.000Z"}
{"max_stars_count": 10, "max_issues_count": 15, "max_forks_count": 3, "avg_line_length": 44.0701754386, "max_line_length": 76, "alphanum_fraction": 0.7539808917}
#lang scribble/doc
@(require "utils.rkt"
          (for-label ffi/unsafe/try-atomic ffi/unsafe/atomic))

@title{Speculatively Atomic Execution}

@defmodule[ffi/unsafe/try-atomic]{The
@racketmodname[ffi/unsafe/try-atomic] library supports atomic execution that
can be suspended and resumed in non-atomic mode if it takes too long
or if some external event causes the attempt to be abandoned.}

@defproc[(call-as-nonatomic-retry-point [thunk (-> any)]) any]{

Calls @racket[thunk] in atomic mode (see @racket[start-atomic] and
@racket[end-atomic]) while allowing @racket[thunk] to use
@racket[try-atomic]. Any incomplete computations started with
@racket[try-atomic] are run non-atomically after @racket[thunk]
returns. The result of @racket[thunk] is used as the result of
@racket[call-as-nonatomic-retry-point].}


@defproc[(try-atomic
          [thunk (-> any)]
          [default-val any/c]
          [#:should-give-up? give-up-proc (-> any/c) _run-200-milliseconds]
          [#:keep-in-order? keep-in-order? any/c #t])
         any]{

Within the dynamic extent of a @racket[call-as-nonatomic-retry-point]
call, attempts to run @racket[thunk] in the existing atomic mode. The
@racket[give-up-proc] procedure is called periodically to determine
whether atomic mode should be abandoned; the default
@racket[give-up-proc] returns true after 200 milliseconds. If atomic
mode is abandoned, the computation is suspended, and
@racket[default-val] is returned, instead. The computation is resumed
later by the enclosing @racket[call-as-nonatomic-retry-point] call.

If @racket[keep-in-order?] is true, then if @racket[try-atomic] is
called after an earlier computation was suspended for the same
@racket[call-as-nonatomic-retry-point] call, then
@racket[thunk] is immediately enqueued for completion by
@racket[call-as-nonatomic-retry-point] and @racket[default-val] is
returned.

The @racket[give-up-proc] callback is polled only at points where the
level of atomic-mode nesting (see @racket[start-atomic],
@racket[start-breakable-atomic], and @racket[call-as-atomic]) is the
same as at the point of calling @racket[try-atomic].

If @racket[thunk] aborts the current continuation using
@racket[(default-continuation-prompt-tag)], the abort is suspended the
resumed by the enclosing
@racket[call-as-nonatomic-retry-point]. Escapes to the context of the
call to @racket[thunk] using any other prompt tag or continuation are
blocked (using @racket[dynamic-wind]) and simply return
@racket[(void)] from @racket[thunk].}
