Skip to content

Commit

Permalink
Fix aio locking on non-linux platforms
Browse files Browse the repository at this point in the history
And improve the tests

Signed-off-by: Steve Bennett <steveb@workware.net.au>
  • Loading branch information
msteveb committed Aug 20, 2016
1 parent dc7c275 commit def038d
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 26 deletions.
4 changes: 4 additions & 0 deletions auto.def
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ if {[cc-check-functions sysinfo]} {
}
}

cc-with {-includes fcntl.h} {
cc-check-types "struct flock"
}

cc-check-lfs
cc-check-functions fseeko ftello

Expand Down
19 changes: 16 additions & 3 deletions jim-aio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1159,10 +1159,16 @@ static int aio_cmd_verify(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
#endif /* JIM_BOOTSTRAP */

#if defined(HAVE_STRUCT_FLOCK) && !defined(JIM_BOOTSTRAP)
static int aio_cmd_lock(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
AioFile *af = Jim_CmdPrivData(interp);
struct flock fl = { F_WRLCK, SEEK_SET, 0, 0 };
struct flock fl;

fl.l_start = 0;
fl.l_len = 0;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;

switch (fcntl(af->fd, F_SETLK, &fl))
{
Expand Down Expand Up @@ -1190,11 +1196,16 @@ static int aio_cmd_lock(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
static int aio_cmd_unlock(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
AioFile *af = Jim_CmdPrivData(interp);
struct flock fl = { F_UNLCK, SEEK_SET, 0, 0 };
struct flock fl;
fl.l_start = 0;
fl.l_len = 0;
fl.l_type = F_UNLCK;
fl.l_whence = SEEK_SET;

Jim_SetResultInt(interp, fcntl(af->fd, F_SETLK, &fl) == 0);
return JIM_OK;
}
#endif /* JIM_BOOTSTRAP */

static const jim_subcmd_type aio_command_table[] = {
{ "read",
Expand Down Expand Up @@ -1370,8 +1381,9 @@ static const jim_subcmd_type aio_command_table[] = {
/* Description: Verifies the certificate of a SSL/TLS channel */
},
#endif /* JIM_BOOTSTRAP */
#if defined(HAVE_STRUCT_FLOCK) && !defined(JIM_BOOTSTRAP)
{ "lock",
NULL,
NULL,
aio_cmd_lock,
0,
0,
Expand All @@ -1384,6 +1396,7 @@ static const jim_subcmd_type aio_command_table[] = {
0,
/* Description: Relase a lock. */
},
#endif /* JIM_BOOTSTRAP */
{ NULL }
};

Expand Down
35 changes: 12 additions & 23 deletions tests/lock.test
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@

source [file dirname [info script]]/testing.tcl

needs constraint jim
# Really we want to check if locking is supported, but there
# is no easy way to do that, so use the existence of os.wait as a proxy
needs cmd os.wait

set fh [open locktest.file w]

test lock-1.1 {grab lock} {
Expand All @@ -29,32 +34,16 @@ test lock-1.4 {release lock again} {
} 1

test lock-1.5 {grab lock from sub-process} {
switch [set pid [os.fork]] {
-1 { error "Fork error." }
0 {
# Child process
$fh lock
sleep 2
puts $fh [$fh unlock]
exit
}
default {
sleep 1
set stat [$fh lock]
set stat
}
}
# Run a child process that grabs the lock for 0.5 seconds
set pid [exec [info nameofexecutable] -e {set fh [open locktest.file r+]; $fh lock; sleep 0.5} >/dev/null &]
sleep 0.1
# Try to grab the lock - should fail
set stat [$fh lock]
sleep 0.5
set stat
} 0

# fcntl() allows unlock on non-held lock so unlock will always return 1
#set x [os.wait $pid]
#test lock-1.6 {check unlock in child process} {
# $fh seek 0 start
# $fh read 1
#} 1

$fh close
file delete locktest.file

testreport

0 comments on commit def038d

Please sign in to comment.