6 # The contents of this file are subject to the terms of the
7 # Common Development and Distribution License (the "License").
8 # You may not use this file except in compliance with the License.
10 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 # or http://www.opensolaris.org/os/licensing.
12 # See the License for the specific language governing permissions
13 # and limitations under the License.
15 # When distributing Covered Code, include this CDDL HEADER in each
16 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 # If applicable, add the following below this CDDL HEADER, with the
18 # fields enclosed by brackets "[]" replaced with your own identifying
19 # information: Portions Copyright [yyyy] [name of copyright owner]
25 # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
29 # filemutexdemo1 - a simple locking demo which supports read/write
30 # locks and critical sections (like JAVA's "syncronized" keyword)
33 # Solaris needs /usr/xpg6/bin:/usr/xpg4/bin because the tools in /usr/bin are not POSIX-conformant
34 export PATH
=/usr
/xpg
6/bin
:/usr
/xpg
4/bin
:/bin
:/usr
/bin
36 # Make sure all math stuff runs in the "C" locale to avoid problems
37 # with alternative # radix point representations (e.g. ',' instead of
38 # '.' in de_DE.*-locales). This needs to be set _before_ any
39 # floating-point constants are defined in this script).
40 if [[ "${LC_ALL}" != "" ]] ; then
42 LC_MONETARY
="${LC_ALL}" \
43 LC_MESSAGES
="${LC_ALL}" \
44 LC_COLLATE
="${LC_ALL}" \
50 # Definition for a mutex which uses the filesystem for locking
51 typeset
-T filemutex_t
=(
56 typeset locked_exclusive
="false"
57 typeset locked_shared
="false"
59 # keep track of subshell level. The problem is that we do not know a
60 # way to figure out whether someone calls "unlock" in a subshell and then
61 # leaves the subshell and calls "unlock" again
66 # create a filemutex instance (including lock directory)
69 # make sure we return an error if the init didn't work
72 [[ "$1" == "" ]] && return 1
75 _.lock_dirname
="/tmp/filemutex_t_${_.name}.lock"
77 mkdir
"${_.lock_dirname}"
79 # last entry, used to mark the mutex as initalised+valid
80 (( _.subshell
=.sh.subshell
))
84 # use a filemutex instance (same as "create" but without creating
88 # make sure we return an error if the init didn't work
91 [[ "$1" == "" ]] && return 1
94 _.lock_dirname
="/tmp/filemutex_t_${_.name}.lock"
96 # last entry, used to mark the mutex as initalised+valid
97 (( _.subshell
=.sh.subshell
))
101 function check_subshell
103 (( _.subshell
== .sh.subshell
)) && return 0
104 print
-u2 -f "filemutex_t.%s(%s): Wrong subshell level\n" "$1" "${_.name}"
108 function try_lock_shared
110 _.check_subshell
"try_lock_shared" ||
return 1
112 mkdir
"${_.lock_dirname}/shared_${PPID}_$$" 2>/dev
/null ||
return 1
113 _.locked_shared
="true"
121 _.check_subshell
"lock_shared" ||
return 1
123 while ! _.try_lock_shared
; do sleep ${interval} ; (( interval
+=interval
/10.
)) ; done
127 function try_lock_exclusive
129 _.check_subshell
"try_lock_exclusive" ||
return 1
131 rmdir "${_.lock_dirname}" 2>/dev
/null ||
return 1
132 _.locked_exclusive
="true"
136 function lock_exclusive
140 _.check_subshell
"lock_exclusive" ||
return 1
142 while ! _.try_lock_exclusive
; do sleep ${interval} ; (( interval
+=interval
/10.
)) ; done
146 # critical section support (like java's "synchronized" keyword)
147 function synchronized
151 _.check_subshell
"synchronized" ||
return 1
163 # critical section support with shared lock
164 function synchronized_shared
168 _.check_subshell
"synchronized_shared" ||
return 1
182 # return an error if rmdir/mkdir/check_subshell fail...
185 _.check_subshell
"unlock"
187 if ${_.locked_shared} ; then
188 rmdir "${_.lock_dirname}/shared_${PPID}_$$"
189 _.locked_shared
="false"
191 elif ${_.locked_exclusive} ; then
192 mkdir
"${_.lock_dirname}"
193 _.locked_exclusive
="false"
197 print
-u2 -f "filemutex_t.unlock(%s): mutex '%s' not locked." "$1" "${_.name}"
201 # destroy mutex if noone is using it anymore (not the same as "unset" !!))
204 _.check_subshell
"destroy" ||
return 1
206 (${_.locked_exclusive} ||
${_.locked_shared}) && _.unlock
207 rmdir "${_.lock_dirname}"
218 typeset
-r mymutexname
="hello_world"
222 fs.create
"${mymutexname}" || print
-u2 "Mutex init failed."
224 print
"# Starting child which keeps an exclusive lock for 10 seconds..."
228 child_fs.create_child
"${mymutexname}"
230 child_fs.lock_exclusive
237 printf "%T: # Waiting to obtain a shared lock...\n"
239 printf "%T: # Obtained shared lock\n"
241 printf "fs.locked_exclusive=%s, fs.locked_shared=%s\n" "${fs.locked_exclusive}" "${fs.locked_shared}"
243 ls -lad /tmp
/filemutex
*/*
245 printf "%T: # Executing child which runs printf '|%%s|\\\n' 'hello' 'world' inside a synchronized section\n"
249 child_fs.create_child
"${mymutexname}"
251 child_fs.synchronized
printf '|%s|\n' 'hello' 'world'
254 printf "%T: # Sleeping 5 secs while holding the shared lock...\n"
257 printf "%T: # Releasing shared lock...\n"
261 print
"# Destroying lock..."