Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
varnishevent3
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
uplex-varnish
varnishevent3
Commits
1bb10f4b
Commit
1bb10f4b
authored
May 11, 2011
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use reference counts to avoid duplicated files in std.fileread().
parent
d30f2a6e
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
55 additions
and
99 deletions
+55
-99
vmod_std_fileread.c
lib/libvmod_std/vmod_std_fileread.c
+55
-99
No files found.
lib/libvmod_std/vmod_std_fileread.c
View file @
1bb10f4b
...
...
@@ -48,119 +48,75 @@
#include "vcc_if.h"
VSLIST_HEAD
(
cached_file_list
,
cached_file
);
struct
cached_file
{
unsigned
magic
;
struct
frfile
{
unsigned
magic
;
#define CACHED_FILE_MAGIC 0xa8e9d87a
char
*
file_name
;
char
*
contents
;
time_t
last_modification
;
ssize_t
file_sz
;
VSLIST_ENTRY
(
cached_file
)
next
;
char
*
file_name
;
char
*
contents
;
int
refcount
;
VTAILQ_ENTRY
(
frfile
)
list
;
};
static
VTAILQ_HEAD
(,
frfile
)
frlist
=
VTAILQ_HEAD_INITIALIZER
(
frlist
);
static
pthread_mutex_t
frmtx
=
PTHREAD_MUTEX_INITIALIZER
;
static
void
free_
cached_files
(
void
*
file_list
)
free_
frfile
(
void
*
ptr
)
{
struct
cached_file
*
iter
,
*
tmp
;
struct
cached_file_list
*
list
=
file_list
;
VSLIST_FOREACH_SAFE
(
iter
,
list
,
next
,
tmp
)
{
CHECK_OBJ
(
iter
,
CACHED_FILE_MAGIC
);
free
(
iter
->
file_name
);
free
(
iter
->
contents
);
FREE_OBJ
(
iter
);
struct
frfile
*
frf
;
CAST_OBJ_NOTNULL
(
frf
,
ptr
,
CACHED_FILE_MAGIC
);
AZ
(
pthread_mutex_lock
(
&
frmtx
));
if
(
--
frf
->
refcount
>
0
)
frf
=
NULL
;
else
VTAILQ_REMOVE
(
&
frlist
,
frf
,
list
);
AZ
(
pthread_mutex_unlock
(
&
frmtx
));
if
(
frf
!=
NULL
)
{
free
(
frf
->
contents
);
free
(
frf
->
file_name
);
FREE_OBJ
(
frf
);
}
free
(
file_list
);
}
static
pthread_rwlock_t
filelist_lock
=
PTHREAD_RWLOCK_INITIALIZER
;
static
int
filelist_update
=
0
;
const
char
*
vmod_fileread
(
struct
sess
*
sp
,
struct
vmod_priv
*
priv
,
const
char
*
file_name
)
{
struct
cached_file
*
iter
=
NULL
;
struct
stat
buf
;
struct
cached_file_list
*
list
;
int
fd
,
my_filelist_update
;
struct
frfile
*
frf
;
char
*
s
;
(
void
)
sp
;
AZ
(
pthread_rwlock_rdlock
(
&
filelist_lock
));
if
(
priv
->
free
==
NULL
)
{
AZ
(
pthread_rwlock_unlock
(
&
filelist_lock
));
/*
* Another thread may already have initialized priv
* here, making the repeat check necessary.
*/
AZ
(
pthread_rwlock_wrlock
(
&
filelist_lock
));
if
(
priv
->
free
==
NULL
)
{
priv
->
free
=
free_cached_files
;
priv
->
priv
=
malloc
(
sizeof
(
struct
cached_file_list
));
AN
(
priv
->
priv
);
list
=
priv
->
priv
;
VSLIST_INIT
(
list
);
}
AZ
(
pthread_rwlock_unlock
(
&
filelist_lock
));
AZ
(
pthread_rwlock_rdlock
(
&
filelist_lock
));
}
else
{
list
=
priv
->
priv
;
VSLIST_FOREACH
(
iter
,
list
,
next
)
{
CHECK_OBJ
(
iter
,
CACHED_FILE_MAGIC
);
if
(
strcmp
(
iter
->
file_name
,
file_name
)
==
0
)
{
/* This thread was holding a read lock. */
AZ
(
pthread_rwlock_unlock
(
&
filelist_lock
));
return
iter
->
contents
;
}
}
AN
(
priv
);
if
(
priv
->
priv
!=
NULL
)
{
CAST_OBJ_NOTNULL
(
frf
,
priv
->
priv
,
CACHED_FILE_MAGIC
);
return
(
frf
->
contents
);
}
my_filelist_update
=
filelist_update
;
/* This thread was holding a read lock. */
AZ
(
pthread_rwlock_unlock
(
&
filelist_lock
));
if
((
fd
=
open
(
file_name
,
O_RDONLY
))
==
-
1
)
return
""
;
AZ
(
fstat
(
fd
,
&
buf
));
AZ
(
pthread_rwlock_wrlock
(
&
filelist_lock
));
if
(
my_filelist_update
!=
filelist_update
)
{
/*
* Small optimization: search through the linked list again
* only if something has been changed.
*/
VSLIST_FOREACH
(
iter
,
list
,
next
)
{
CHECK_OBJ
(
iter
,
CACHED_FILE_MAGIC
);
if
(
strcmp
(
iter
->
file_name
,
file_name
)
==
0
)
{
/* This thread was holding a write lock. */
AZ
(
pthread_rwlock_unlock
(
&
filelist_lock
));
return
iter
->
contents
;
}
AZ
(
pthread_mutex_lock
(
&
frmtx
));
VTAILQ_FOREACH
(
frf
,
&
frlist
,
list
)
{
if
(
!
strcmp
(
file_name
,
frf
->
file_name
))
{
frf
->
refcount
++
;
break
;
}
}
ALLOC_OBJ
(
iter
,
CACHED_FILE_MAGIC
);
AN
(
iter
);
iter
->
file_name
=
strdup
(
file_name
);
i
ter
->
last_modification
=
buf
.
st_mtime
;
iter
->
contents
=
vreadfd
(
fd
,
&
iter
->
file_sz
);
AN
(
iter
->
contents
);
assert
(
iter
->
file_sz
==
buf
.
st_siz
e
);
AZ
(
close
(
fd
))
;
VSLIST_INSERT_HEAD
(
list
,
iter
,
next
)
;
filelist_update
++
;
/* This thread was holding a write lock. */
AZ
(
pthread_rwlock_unlock
(
&
filelist_lock
));
return
iter
->
contents
;
AZ
(
pthread_mutex_unlock
(
&
frmtx
));
if
(
frf
!=
NULL
)
return
(
frf
->
contents
);
s
=
vreadfile
(
NULL
,
file_name
,
NULL
);
i
f
(
s
!=
NULL
)
{
ALLOC_OBJ
(
frf
,
CACHED_FILE_MAGIC
);
AN
(
frf
);
frf
->
file_name
=
strdup
(
file_name
);
AN
(
frf
->
file_nam
e
);
frf
->
refcount
=
1
;
frf
->
contents
=
s
;
priv
->
free
=
free_frfile
;
priv
->
priv
=
frf
;
AZ
(
pthread_mutex_lock
(
&
frmtx
))
;
VTAILQ_INSERT_HEAD
(
&
frlist
,
frf
,
list
);
AZ
(
pthread_mutex_unlock
(
&
frmtx
));
}
return
(
s
)
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment