Only server should control fifo; client should wait for it to clear
On the a classic “concurrency is hard” front, I am slightly proud of myself that I didn't hit this race condition but anticipated that it might occur later. Giving entire control to fifoName to the server makes more sense here, and the client should not submit its query any time either fifoName or question is set. As an extra safeguard, the client will die if it gets the lock and the state for submitting a query isn't right. Finally, added some fifoName removal debugging on the server.
This commit is contained in:
parent
42800427f6
commit
8349b9610b
2 changed files with 15 additions and 2 deletions
|
@ -17,8 +17,15 @@ sub BeancountQueryInitialize {
|
||||||
|
|
||||||
sub BeancountQuerySubmit($) {
|
sub BeancountQuerySubmit($) {
|
||||||
my($question) = @_;
|
my($question) = @_;
|
||||||
|
while (defined $BEANCOUNT_QUERY{fifoName} or defined $BEANCOUNT_QUERY{question}) { sleep 1; }
|
||||||
(tied %BEANCOUNT_QUERY)->shlock;
|
(tied %BEANCOUNT_QUERY)->shlock;
|
||||||
$BEANCOUNT_QUERY{fifoName} = undef;
|
if (defined $BEANCOUNT_QUERY{fifoName} or defined $BEANCOUNT_QUERY{question}) {
|
||||||
|
(tied %BEANCOUNT_QUERY)->shunlock;
|
||||||
|
no warnings 'uninitialized';
|
||||||
|
die("caught lock to submit a query, but either fifoName or question was defined, " .
|
||||||
|
"so something is wrong here. " .
|
||||||
|
"fifoName: \"$BEANCOUNT_QUERY{fifoName}\" question: \"$BEANCOUNT_QUERY{question}\"!");
|
||||||
|
}
|
||||||
$BEANCOUNT_QUERY{question} = $question;
|
$BEANCOUNT_QUERY{question} = $question;
|
||||||
(tied %BEANCOUNT_QUERY)->shunlock;
|
(tied %BEANCOUNT_QUERY)->shunlock;
|
||||||
while (not defined $BEANCOUNT_QUERY{fifoName}) { sleep 1; }
|
while (not defined $BEANCOUNT_QUERY{fifoName}) { sleep 1; }
|
||||||
|
|
|
@ -71,11 +71,17 @@ tie %beancountData, 'IPC::Shareable', $glue, { %options } or
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (not defined $query{question}) {
|
if (not defined $query{question}) {
|
||||||
print STDERR "No question posed, sleeping 2\n" if $VERBOSE > 2;
|
print STDERR "No question posed..." if $VERBOSE > 2;
|
||||||
if (defined $query{fifoName}) {
|
if (defined $query{fifoName}) {
|
||||||
|
print STDERR "fifo still active; locking to clear it..." if $VERBOSE > 2;
|
||||||
|
(tied %query)->shlock;
|
||||||
|
print STDERR "clearing fifo, $query{fifoName}..." if $VERBOSE > 2;
|
||||||
no autodie 'unlink'; unlink($query{fifoName});
|
no autodie 'unlink'; unlink($query{fifoName});
|
||||||
$query{fifoName} = undef;
|
$query{fifoName} = undef;
|
||||||
|
(tied %query)->shunlock;
|
||||||
|
print STDERR "fifo cleared & lock released." if $VERBOSE > 2;
|
||||||
}
|
}
|
||||||
|
print STDERR "sleep for 2 seconds\n" if $VERBOSE > 2;
|
||||||
sleep 2;
|
sleep 2;
|
||||||
next;
|
next;
|
||||||
} elsif ($query{question} !~ /^[\-\@\w.\s\"\'\_\(\)]+$/) {
|
} elsif ($query{question} !~ /^[\-\@\w.\s\"\'\_\(\)]+$/) {
|
||||||
|
|
Loading…
Reference in a new issue