Back
locking (clj)
(source)macro
(locking x & body)
Executes exprs in an implicit do, while holding the monitor of x.
Will release the monitor of x in all circumstances.
Examples
clojure/core.async
;; The clojure.core.async namespace contains the public API.
(require '[clojure.core.async :as async :refer :all])
;; In ordinary threads, we use `>!!` (blocking put) and `<!!`
;; (blocking take) to communicate via channels.
;; Because these are blocking calls, if we try to put on an
;; unbuffered channel, we will block the main thread. We can use
;; `thread` (like `future`) to execute a body in a pool thread and
;; return a channel with the result. Here we launch a background task
;; to put "hello" on a channel, then read that value in the current thread.
;; The `go` macro asynchronously executes its body in a special pool
;; of threads. Channel operations that would block will pause
;; execution instead, blocking no threads. This mechanism encapsulates
;; the inversion of control that is external in event/callback
;; systems. Inside `go` blocks, we use `>!` (put) and `<!` (take).
;; Instead of the explicit thread and blocking call, we use a go block
;; for the producer. The consumer uses a go block to take, then
;; returns a result channel, from which we do a blocking take.
clojure/core.typed
(ns ^:skip-wiki clojure.core.typed.ann.clojure
"Type annotations for the base Clojure distribution."
(:require [#?(:clj clojure.core.typed
:cljs cljs.core.typed)
:refer [defalias] :as t]))
(defalias
^{:doc "A Clojure future (see clojure.core/{future-call,future})."
:forms '[(Future t)]}
t/Future
(t/TFn [[x :variance :covariant]]
(t/I (t/Deref x)
(clojure.lang.IBlockingDeref x)
clojure.lang.IPending
java.util.concurrent.Future)))
(defalias
^{:doc "A Clojure promise (see clojure.core/{promise,deliver})."
:forms '[(Promise t)]}
t/Promise
(t/TFn [[x :variance :invariant]]
(t/Rec [p]
(t/I (t/Deref x)
(clojure.lang.IBlockingDeref x)
clojure.lang.IPending
[x -> (t/U nil p)]))))
(defalias
^{:doc "A Clojure blocking derefable (see clojure.core/deref)."
:forms '[(BlockingDeref t)]}
t/BlockingDeref
(t/TFn [[x :variance :covariant]]
(clojure.lang.IBlockingDeref x)))
hraberg/deuce
(ns deuce.emacs.fileio
(:use [deuce.emacs-lisp :only (defun defvar) :as el])
(:require [clojure.core :as c]
[clojure.string :as s]
[clojure.java.io :as io]
[deuce.emacs.buffer :as buffer]
[deuce.emacs.data :as data]
[deuce.emacs.eval :as eval]
[deuce.emacs.editfns :as editfns])
(:import [java.nio.file Files LinkOption
NoSuchFileException]
[deuce.emacs.data Buffer BufferText])
(:refer-clojure :exclude []))
Optional fourth argument APPEND if non-nil means
append to existing file contents (if any). If it is an integer,
seek to that offset in the file before writing.
Optional fifth argument VISIT, if t or a string, means
set the last-save-file-modtime of buffer to this file's modtime
and mark buffer not modified.
If VISIT is a string, it is a second file name;
the output goes to FILENAME, but the buffer is marked as visiting VISIT.
VISIT is also the file name to lock and unlock for clash detection.
If VISIT is neither t nor nil nor a string,
that means do not display the \"Wrote file\" message.
The optional sixth arg LOCKNAME, if non-nil, specifies the name to
use for locking and unlocking, overriding FILENAME and VISIT.
The optional seventh arg MUSTBENEW, if non-nil, insists on a check
for an existing file with the same name. If MUSTBENEW is `excl',
that means to get an error if the file already exists; never overwrite.
If MUSTBENEW is neither nil nor `excl', that means ask for
confirmation before overwriting, but do go ahead and overwrite the file
if the user confirms.
typedclojure/typedclojure
End users should use typed.lib.clojure.core.async, which all types here
are qualified under."}
typed.ann.clojure.core.async
(:require [typed.clojure :refer [ann ann-datatype defalias ann-protocol] :as t]
[typed.lib.clojure.core.async :as-alias ta]
[clojure.core.async.impl.protocols :as-alias impl])
(:import (java.util.concurrent.locks Lock)))
(ann-protocol clojure.core.async.impl.protocols/UnblockingBuffer)
(defalias
^{:forms '[(UnblockingBuffer2 t t)]}
ta/UnblockingBuffer2
"An unblocking buffer that can write type w and read type t."
(t/TFn [[w :variance :contravariant]
[r :variance :covariant]]
(t/I (ta/Buffer2 w r)
impl/UnblockingBuffer)))
(defalias
^{:forms '[(UnblockingBuffer t)]}
ta/UnblockingBuffer
"An unblocking buffer of type x."
(t/TFn [[x :variance :invariant]]
(ta/UnblockingBuffer2 x x)))
typedclojure/typedclojure
(ns ^:no-doc typed.ann.clojure
"Type annotations for the base Clojure distribution."
#?(:cljs (:require-macros [typed.ann-macros.clojure :as macros]))
(:require [clojure.core :as cc]
[typed.clojure :as t]
#?(:clj [typed.ann-macros.clojure :as macros])
#?(:clj typed.ann.clojure.jvm) ;; jvm annotations
#?(:clj clojure.core.typed))
#?(:clj
(:import (clojure.lang PersistentHashSet PersistentList
APersistentMap #_IPersistentCollection
#_ITransientSet
IRef)
(java.util Comparator Collection))))
#?(:clj
(t/defalias
^{:doc "A Clojure future (see clojure.core/{future-call,future})."
:forms '[(Future x)]}
t/Future
(t/TFn [[x :variance :covariant]]
(t/I (t/Deref x)
(clojure.lang.IBlockingDeref x)
clojure.lang.IPending
java.util.concurrent.Future))))
#?(:clj
(t/defalias
^{:doc "A Clojure promise (see clojure.core/{promise,deliver})."
:forms '[(Promise x)]}
t/Promise
(t/TFn [[x :variance :invariant]]
(t/I (t/Deref x)
(clojure.lang.IBlockingDeref x)
clojure.lang.IPending
;; FIXME I think this might be an implementation detail.
[x :-> (t/Nilable (t/Promise x))]))))
(t/defalias
^{:doc "A Clojure blocking derefable (see clojure.core/deref)."
:forms '[(BlockingDeref x)]}
t/BlockingDeref
(t/TFn [[x :variance :covariant]]
#?(:clj (clojure.lang.IBlockingDeref x)
:cljs (cljs.core/IDerefWithTimeout x))))
cc/deref (t/All [x #?(:clj y)]
(t/IFn
[(t/Deref x) :-> x]
#?(:clj [(t/U (t/Deref t/Any) java.util.concurrent.Future) :-> t/Any])
#?(:clj [(t/BlockingDeref x) t/AnyInteger y :-> (t/U x y)])
#?(:clj [(t/U java.util.concurrent.Future (t/BlockingDeref t/Any)) t/AnyInteger t/Any :-> t/Any])))