home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
FAQ
/
discus_admin_1357211388
/
source
/
dtaskman.pl
< prev
next >
Wrap
Text File
|
2009-11-06
|
6KB
|
267 lines
# FILE: dtaskman.pl
# DESCRIPTION: Discus task manager daemon
#-------------------------------------------------------------------------------
# DISCUS COPYRIGHT NOTICE
#
# Discus is copyright (c) 2002 by DiscusWare, LLC, all rights reserved.
# The use of Discus is governed by the Discus License Agreement which is
# available from the Discus WWW site at:
# http://www.discusware.com/discus/license
#
# Pursuant to the Discus License Agreement, this copyright notice may not be
# removed or altered in any way.
#-------------------------------------------------------------------------------
use strict;
use vars qw($GLOBAL_OPTIONS $PARAMS $DCONF);
###
### taskman_init
###
### Initializes the task mananger
###
sub taskman_init {
if ($DCONF->{pro} && $GLOBAL_OPTIONS->{discus_schedman}) {
taskman_create_job("schedule_daemon_start", "schedule-PRO", undef);
}
my $timecache = time;
my $pid_file = "$DCONF->{admin_dir}/data/dtaskman.pid";
if (my @j = stat $pid_file) {
unlink $pid_file if $j[9] < (time - 90);
return if -e $pid_file;
}
unless (my $pid = fork) { # task manager daemon itself
my $mask = umask(0333);
if (open (FILE, "> $pid_file")) {
print FILE $$;
close (FILE);
umask($mask);
} else {
program_exit(0);
}
$SIG{INT} = sub { unlink "$DCONF->{admin_dir}/data/dtaskman.pid"; program_exit(0); } ;
$SIG{TERM} = sub { unlink "$DCONF->{admin_dir}/data/dtaskman.pid"; program_exit(0); } ;
close STDOUT; close STDIN; close STDERR;
taskman_daemon();
}
return;
}
###
### taskman_check_process_id
###
### Checks to make sure that this is the desired task manager, and if not, exits
###
sub taskman_check_process_id {
my ($pidfile, $mypid) = @_;
$mypid = $$ if ! $mypid;
if (open(FILE, "< $pidfile")) {
my @file = <FILE>;
close (FILE);
program_exit(0) if $mypid != $file[0];
} else {
program_exit(0);
}
}
###
### taskman_daemon
###
### The task manager itself
###
sub taskman_daemon_spawn;
sub taskman_daemon {
my $taskman_dir = join("/", $DCONF->{admin_dir}, "data", "dtaskman");
my $pid_file = "$DCONF->{admin_dir}/data/dtaskman.pid";
if (! -e $taskman_dir) {
mkdir($taskman_dir, oct($DCONF->{perms0777})) || taskman_force_exit();
chmod(oct($DCONF->{perms0777}), $taskman_dir);
}
my $DEBUG_PROC = 1;
my $iterations = 0;
W: while (-e $pid_file && $iterations < 100) {
sleep 1;
$iterations++;
my $now = time;
utime $now, $now, $pid_file;
taskman_check_process_id($pid_file, $$);
if (opendir(DIR, $taskman_dir)) {
my @dir = map {"$taskman_dir/$_"} grep {not /^\.\.?$/} readdir DIR;
closedir(DIR);
F: foreach my $file (@dir) {
next F if ! -f $file;
my $mtime = (stat $file)[9];
next F if (12+$mtime) > $now; # Prevent locking with calling process
if ($DEBUG_PROC) {
open (STDERR, "> $DCONF->{admin_dir}/data/taskman.err") if $DEBUG_PROC;
print STDERR "Starting task manager daemon $$\n" if $DEBUG_PROC;
print STDERR "File: $file\n" if $DEBUG_PROC;
}
if (open(FILE, "< $file")) {
my @file = <FILE>;
close (FILE);
if (unlink $file) {
taskman_daemon_spawn sub {
my $subroutine = shift @file; chomp $subroutine;
my $subfile = shift @file; chomp $subfile;
my @args = taskman_unencode_arguments(\@file);
if ($DEBUG_PROC) {
dreq("debug");
my $fh = select(STDERR);
print "Subroutine: $subroutine\n";
print "File: $subfile\n";
array_dump(\@args, 0, 'Arguments');
select($fh);
}
dreq("$subfile");
my $sh = \&{ $subroutine };
&{ $sh }(@args);
};
}
}
close (STDERR) if $DEBUG_PROC;
my $now = time;
utime $now, $now, "$DCONF->{admin_dir}/data/dtaskman.pid";
}
next W if scalar(@dir);
}
sleep 4;
if ($DCONF->{pro} && $GLOBAL_OPTIONS->{discus_schedman} && ! -e "$DCONF->{admin_dir}/data/schedule.pid") {
if ($GLOBAL_OPTIONS->{maintenance} == 0) {
taskman_create_job("schedule_daemon_start", "schedule-PRO", undef);
}
}
}
program_exit(0) if ! -e "$DCONF->{admin_dir}/data/dtaskman.pid";
unlink "$DCONF->{admin_dir}/data/dtaskman.pid";
taskman_init();
program_exit(0);
}
###
### taskman_daemon_spawn
###
### Creates a child process to perform a task
###
sub taskman_daemon_spawn {
my $coderef = shift;
unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') {
return undef;
}
my $pid;
if (!defined($pid = fork)) {
log_error("dtaskman.pl", "taskman_daemon_spawn", "cannot fork: $!");
return undef;
} elsif ($pid) {
wait;
return;
}
program_exit(&$coderef());
}
###
### taskman_create_job
###
### Creates a job for the task manager to do later
###
sub taskman_create_job {
my ($subroutine, $subfile, $arg_list) = @_;
my $taskman_dir = join("/", $DCONF->{admin_dir}, "data", "dtaskman");
my $jobnum = join("", substr(time, length(time) - 4, 4), substr($$, 0, 4)); $jobnum =~ s/\D//g;
$jobnum += int(rand(10)) while -r "$taskman_dir/$jobnum.txt";
open (JOBFILE, "> $taskman_dir/$jobnum.txt");
print JOBFILE "$subroutine\n";
print JOBFILE "$subfile\n";
my @args = taskman_encode_arguments(@{ $arg_list });
foreach my $x (@args) {
print JOBFILE $x, "\n";
}
close (JOBFILE);
return $jobnum;
}
###
### taskman_encode_arguments
###
### Encodes subroutine arguments
###
sub taskman_encode_arguments {
dreq("storage");
return storage_encode_arguments(@_);
}
###
### taskman_unencode_arguments
###
### Unencodes an argument list
###
sub taskman_unencode_arguments {
dreq("storage");
return storage_unencode_arguments(@_);
}
###
### taskman_unencode_hash
###
### Transforms an encoded hash into an unencoded hash
###
sub taskman_unencode_hash {
dreq("storage");
return storage_unencode_hash(@_);
}
###
### taskman_unencode_array
###
### Transforms an encoded array into an unencoded array
###
sub taskman_unencode_array {
dreq("storage");
return storage_unencode_array (@_);
}
###
### taskman_encode_hash
###
### Transforms an unencoded hash into an encoded hash
###
sub taskman_encode_hash {
dreq("storage");
return storage_encode_hash (@_);
}
###
### taskman_encode_array
###
### Transforms an unencoded array into an encoded array
###
sub taskman_encode_array {
dreq("storage");
return taskman_encode_array(@_);
}
###
### taskman_force_exit
###
### Abnormal exists from the task manager
###
sub taskman_force_exit {
unlink "$DCONF->{admin_dir}/data/dtaskman.pid";
program_exit(0);
}
1;