ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/lib/cf/incloader.pm
Revision: 1.3
Committed: Thu May 13 12:25:12 2010 UTC (14 years, 1 month ago) by root
Branch: MAIN
Changes since 1.2: +17 -3 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #
2     # This file is part of Deliantra, the Roguelike Realtime MMORPG.
3     #
4     # Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5     #
6     # Deliantra is free software: you can redistribute it and/or modify it under
7     # the terms of the Affero GNU General Public License as published by the
8     # Free Software Foundation, either version 3 of the License, or (at your
9     # option) any later version.
10     #
11     # This program is distributed in the hope that it will be useful,
12     # but WITHOUT ANY WARRANTY; without even the implied warranty of
13     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     # GNU General Public License for more details.
15     #
16     # You should have received a copy of the Affero GNU General Public License
17     # and the GNU General Public License along with this program. If not, see
18     # <http://www.gnu.org/licenses/>.
19     #
20     # The authors can be reached via e-mail to <support@deliantra.net>
21     #
22    
23     package cf::incloader;
24    
25     use common::sense;
26    
27 root 1.2 our $PID = $$;
28    
29 root 1.1 # async inc loader. yay.
30     sub inc_loader {
31     my $mod = $_[1];
32    
33 root 1.2 return if $$ != $PID; # do not do this in child processes
34    
35 root 1.1 if (cf::in_main && !cf::tick_inhibit) {
36     Carp::cluck "ERROR: attempted synchronous perl module load ($mod)";
37 root 1.3 return; # do it blockingly
38 root 1.1 } else {
39     cf::debug "loading perl module $mod\n";
40     }
41    
42     # find real file
43     for my $dir (@cf::ORIG_INC) {
44     ref $dir and next;
45    
46     my $path = "$dir/$mod";
47    
48     # avoid upgrade when prepending #line
49     utf8::downgrade $path, 1;
50    
51     0 <= Coro::AIO::aio_load $path, my $data
52     or next;
53    
54     $data = "#line 1 $path\n$data";
55    
56     # hackish way to pre-cache .so/.bs files
57     if ($path =~ s/\.pm$//) {
58     my @c = split /\//, $path;
59     for (reverse 2 .. $#c) {
60     my $a = join "/", @c[0..$_-1];
61     my $b = join "/", @c[$_..$#c];
62    
63     Coro::AIO::aio_stat "$a/auto/$b/."
64     and next;
65    
66     $path = "$a/auto/$b/";
67    
68     cf::debug "pre-caching $path";
69    
70     my $files = Coro::AIO::aio_readdir $path;
71    
72     my $grp = IO::AIO::aio_group;
73    
74     for my $file (@$files) {
75     next if $file =~ /(^\.packlist|\.h$|\.xst$)/;
76    
77     add $grp IO::AIO::aio_open "$path/$file", IO::AIO::O_RDONLY, 0, sub {
78     my ($fh) = @_
79     or return;
80    
81     add $grp IO::AIO::aio_stat $fh, sub {
82     my $size = -s _;
83    
84     add $grp IO::AIO::aio_readahead $fh, 0, $size;
85    
86     cf::debug "pre-caching $path/$file ($size)";
87     };
88     };
89     }
90    
91     Coro::AIO::aio_wait $grp;
92     last;
93     }
94     }
95    
96     die if utf8::is_utf8 $data;#d#
97     open my $fh, "<", \$data or die;
98    
99     cf::get_slot 0.1, 10, "\@INC loader";
100    
101     return $fh;
102     }
103    
104     ()
105     }
106    
107 root 1.3 sub preload_stuff {
108     # load some stuff so perl doesn't load it later... :/
109    
110     eval { &Storable::nstore_fd };
111    
112     require 'utf8_heavy.pl';
113     require 'unicore/PVA.pl';
114     require 'unicore/To/Fold.pl';
115     require 'unicore/To/Digit.pl';
116     require 'unicore/To/Lower.pl';
117     require 'unicore/To/Upper.pl';
118     require 'unicore/To/Title.pl';
119     #TODO# load whole unicore, really.
120     }
121    
122 root 1.1 sub init {
123     # save original @INC
124     @cf::ORIG_INC = ($cf::LIBDIR, @INC) unless @cf::ORIG_INC;
125    
126     # make sure we can do scalar-opens
127     open my $dummy, "<", \my $dummy2;
128    
129 root 1.3 preload_stuff;
130 root 1.1
131     @INC = (\&inc_loader, @cf::ORIG_INC); # @ORIG_INC is needed for DynaLoader, AutoLoad etc.
132    
133     cf::debug "module loading will be asynchronous from this point on.";
134     }
135    
136     1