← Index
NYTProf Performance Profile   « line view »
For /usr/local/libexec/sympa/task_manager-debug.pl
  Run on Tue Jun 1 22:32:51 2021
Reported on Tue Jun 1 22:35:09 2021

Filename/usr/local/libexec/sympa/Sympa/LockedFile.pm
StatementsExecuted 23873 statements in 49.7ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11781128.3ms398msSympa::LockedFile::::openSympa::LockedFile::open
11785312.4ms105msSympa::LockedFile::::DESTROYSympa::LockedFile::DESTROY
24082110.9ms10.9msSympa::LockedFile::::__ANON__[:49]Sympa::LockedFile::__ANON__[:49]
1178111.76ms1.76msSympa::LockedFile::::CORE:matchSympa::LockedFile::CORE:match (opcode)
2842473µs7.46msSympa::LockedFile::::closeSympa::LockedFile::close
0000s0sSympa::LockedFile::::BEGIN@27Sympa::LockedFile::BEGIN@27
0000s0sSympa::LockedFile::::BEGIN@28Sympa::LockedFile::BEGIN@28
0000s0sSympa::LockedFile::::BEGIN@29Sympa::LockedFile::BEGIN@29
0000s0sSympa::LockedFile::::BEGIN@31Sympa::LockedFile::BEGIN@31
0000s0sSympa::LockedFile::::BEGIN@33Sympa::LockedFile::BEGIN@33
0000s0sSympa::LockedFile::::BEGIN@35Sympa::LockedFile::BEGIN@35
0000s0sSympa::LockedFile::::BEGIN@36Sympa::LockedFile::BEGIN@36
0000s0sSympa::LockedFile::::basenameSympa::LockedFile::basename
0000s0sSympa::LockedFile::::extendSympa::LockedFile::extend
0000s0sSympa::LockedFile::::last_errorSympa::LockedFile::last_error
0000s0sSympa::LockedFile::::renameSympa::LockedFile::rename
0000s0sSympa::LockedFile::::unlinkSympa::LockedFile::unlink
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# -*- indent-tabs-mode: nil; -*-
2# vim:ft=perl:et:sw=4
3# $Id$
4
5# Sympa - SYsteme de Multi-Postage Automatique
6#
7# Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel
8# Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
9# 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites
10# Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017 GIP RENATER
11#
12# This program is free software; you can redistribute it and/or modify
13# it under the terms of the GNU General Public License as published by
14# the Free Software Foundation; either version 2 of the License, or
15# (at your option) any later version.
16#
17# This program is distributed in the hope that it will be useful,
18# but WITHOUT ANY WARRANTY; without even the implied warranty of
19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20# GNU General Public License for more details.
21#
22# You should have received a copy of the GNU General Public License
23# along with this program. If not, see <http://www.gnu.org/licenses/>.
24
25package Sympa::LockedFile;
26
27use strict;
28use warnings;
29use English qw(-no_match_vars);
30
31use base qw(IO::File);
32
33use File::NFSLock;
34
35BEGIN {
36 no warnings 'redefine';
37
38 # Separate extensions with "," to avoid confusion with domain parts,
39 # and to ensure that file names related to lock contains ",lock".
40 $File::NFSLock::LOCK_EXTENSION = ',lock';
41
# spent 10.9ms within Sympa::LockedFile::__ANON__[/usr/local/libexec/sympa/Sympa/LockedFile.pm:49] which was called 2408 times, avg 5µs/call: # 1204 times (6.32ms+0s) by File::NFSLock::new at line 126 of File/NFSLock.pm, avg 5µs/call # 1204 times (4.61ms+0s) by File::NFSLock::uncache at line 432 of File/NFSLock.pm, avg 4µs/call
*File::NFSLock::rand_file = sub($) {
422408671µs my $file = shift;
43 return
44240823.3ms $file
45 . ',lock.'
46 . time() % 10000 . '.'
47 . $PID . '.'
48 . int(rand() * 10000);
49 };
50}
51
52our %lock_of;
53our $last_error;
54my $default_timeout = 30;
55my $stale_lock_timeout = 20 * 60; # TODO might become a config parameter
56
57sub last_error { $last_error; }
58
59
# spent 398ms (28.3+370) within Sympa::LockedFile::open which was called 1178 times, avg 338µs/call: # 1178 times (28.3ms+370ms) by IO::File::new at line 160 of IO/File.pm, avg 338µs/call
sub open {
601178257µs my $self = shift;
611178304µs my $file = shift;
621178400µs my $blocking_timeout = shift || $default_timeout;
631178348µs my $mode = shift || '<';
64
651178203µs my $lock_type;
6611784.03ms11781.76ms if ($mode =~ /[+>aw]/) {
# spent 1.76ms making 1178 calls to Sympa::LockedFile::CORE:match, avg 1µs/call
67 $lock_type = File::NFSLock::LOCK_EX();
68 } else {
69135µs $lock_type = File::NFSLock::LOCK_SH();
70 }
711178663µs if ($blocking_timeout < 0) {
72 $lock_type |= File::NFSLock::LOCK_NB();
73 }
74
751178346µs undef $last_error;
76
7711784.95ms1178329ms my $lock = File::NFSLock->new(
# spent 329ms making 1178 calls to File::NFSLock::new, avg 280µs/call
78 { file => $file,
79 lock_type => $lock_type,
80 blocking_timeout => $blocking_timeout,
81 stale_lock_timeout => $stale_lock_timeout,
82 }
83 );
841178267µs unless ($lock) {
85 $last_error = $File::NFSLock::errstr || 'Unknown error';
86 return undef;
87 }
88
891178712µs if ($mode ne '+') {
9011781.96ms117838.7ms unless ($self->SUPER::open($file, $mode)) {
# spent 38.7ms making 1178 calls to IO::File::open, avg 33µs/call
91 $last_error = $ERRNO || 'Unknown error';
92 $lock->unlock; # make sure unlock to occur immediately.
93 return undef;
94 }
95 }
96
9711781.74ms $lock_of{$self + 0} = $lock; # register lock object, i.e. keep locking.
9811782.31ms return 1;
99}
100
101
# spent 7.46ms (473µs+6.98) within Sympa::LockedFile::close which was called 28 times, avg 266µs/call: # 13 times (212µs+5.81ms) by Sympa::List::_load_list_config_file at line 5209 of /usr/local/libexec/sympa/Sympa/List.pm, avg 463µs/call # 13 times (177µs+905µs) by Sympa::List::load at line 725 of /usr/local/libexec/sympa/Sympa/List.pm, avg 83µs/call # once (65µs+194µs) by Sympa::Process::write_pid at line 371 of /usr/local/libexec/sympa/Sympa/Process.pm # once (19µs+75µs) by Sympa::Process::remove_pid at line 283 of /usr/local/libexec/sympa/Sympa/Process.pm
sub close {
102289µs my $self = shift;
103
104287µs my $ret;
10528120µs56287µs if (defined $self->fileno) {
# spent 231µs making 28 calls to IO::Handle::close, avg 8µs/call # spent 56µs making 28 calls to IO::Handle::fileno, avg 2µs/call
106 $ret = $self->SUPER::close;
107 } else {
108 $ret = 1;
109 }
110
1112832µs die 'Lock not found' unless exists $lock_of{$self + 0};
112
1132852µs286.61ms $lock_of{$self + 0}->unlock; # make sure unlock to occur immediately.
# spent 6.61ms making 28 calls to File::NFSLock::unlock, avg 236µs/call
11428132µs2888µs delete $lock_of{$self + 0}; # lock object will be destructed.
# spent 88µs making 28 calls to File::NFSLock::DESTROY, avg 3µs/call
1152862µs return $ret;
116}
117
118sub extend {
119 my $self = shift;
120
121 die 'Lock not fould' unless exists $lock_of{$self + 0};
122
123 undef $last_error;
124 unless (utime undef, undef, $lock_of{$self + 0}->{lock_file}) {
125 $last_error = $ERRNO;
126 return undef;
127 }
128
129 return 1;
130}
131
132sub basename {
133 my $self = shift;
134 my $level = shift || 0;
135
136 die 'Lock not found' unless exists $lock_of{$self + 0};
137
138 my @paths = reverse split '/', $lock_of{$self + 0}->{file};
139 return $paths[$level];
140}
141
142sub rename {
143 my $self = shift;
144 my $destfile = shift;
145
146 die 'Lock not found' unless exists $lock_of{$self + 0};
147
148 undef $last_error;
149 my $lock = $lock_of{$self + 0};
150
151 unless ($lock->{lock_type} & File::NFSLock::LOCK_EX()) {
152 $last_error = 'Not the exclusive lock';
153 return undef;
154 }
155
156 my $dest = (ref $self)->new($destfile, -1, '+') or return undef;
157 if (defined $self->fileno) {
158 $self->SUPER::close;
159 }
160 unless (rename $lock->{file}, $destfile) {
161 my $error = $ERRNO;
162 $dest->close;
163 $last_error = $error;
164 return undef;
165 }
166 $self->close;
167 $dest->close;
168
169 return 1;
170}
171
172sub unlink {
173 my $self = shift;
174
175 die 'Lock not found' unless exists $lock_of{$self + 0};
176
177 undef $last_error;
178 if ($lock_of{$self + 0}->{file}) {
179 unless (unlink $lock_of{$self + 0}->{file}) {
180 $last_error = $ERRNO;
181 return undef;
182 }
183 }
184
185 return $self->close;
186}
187
188# Destruct inside reference to lock object so that it will be released.
189# Corresponding filehandle will be closed automatically.
190
# spent 105ms (12.4+92.4) within Sympa::LockedFile::DESTROY which was called 1178 times, avg 89µs/call: # 1150 times (12.3ms+92.4ms) by Sympa::Spool::next at line 155 of /usr/local/libexec/sympa/Sympa/Spool.pm, avg 91µs/call # 13 times (35µs+0s) by Sympa::List::_load_list_config_file at line 5269 of /usr/local/libexec/sympa/Sympa/List.pm, avg 3µs/call # 13 times (17µs+0s) by Sympa::List::load at line 725 of /usr/local/libexec/sympa/Sympa/List.pm, avg 1µs/call # once (3µs+0s) by Sympa::Process::write_pid at line 373 of /usr/local/libexec/sympa/Sympa/Process.pm # once (1µs+0s) by Sympa::Process::remove_pid at line 284 of /usr/local/libexec/sympa/Sympa/Process.pm
sub DESTROY {
1911178239µs my $self = shift;
19211786.55ms115092.4ms delete $lock_of{$self + 0}; # lock object will be destructed.
# spent 92.4ms making 1150 calls to File::NFSLock::DESTROY, avg 80µs/call
193}
194
1951;
196__END__
 
# spent 1.76ms within Sympa::LockedFile::CORE:match which was called 1178 times, avg 1µs/call: # 1178 times (1.76ms+0s) by Sympa::LockedFile::open at line 66, avg 1µs/call
sub Sympa::LockedFile::CORE:match; # opcode