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 >
Text File  |  2009-11-06  |  6KB  |  267 lines

  1. # FILE: dtaskman.pl
  2. # DESCRIPTION: Discus task manager daemon
  3. #-------------------------------------------------------------------------------
  4. # DISCUS COPYRIGHT NOTICE
  5. #
  6. # Discus is copyright (c) 2002 by DiscusWare, LLC, all rights reserved.
  7. # The use of Discus is governed by the Discus License Agreement which is
  8. # available from the Discus WWW site at:
  9. #    http://www.discusware.com/discus/license
  10. #
  11. # Pursuant to the Discus License Agreement, this copyright notice may not be
  12. # removed or altered in any way.
  13. #-------------------------------------------------------------------------------
  14.  
  15. use strict;
  16. use vars qw($GLOBAL_OPTIONS $PARAMS $DCONF);
  17.  
  18. ###
  19. ### taskman_init
  20. ###
  21. ### Initializes the task mananger
  22. ###
  23.  
  24. sub taskman_init {
  25.     if ($DCONF->{pro} && $GLOBAL_OPTIONS->{discus_schedman}) {
  26.         taskman_create_job("schedule_daemon_start", "schedule-PRO", undef);
  27.     }
  28.     my $timecache = time;
  29.     my $pid_file = "$DCONF->{admin_dir}/data/dtaskman.pid";
  30.     if (my @j = stat $pid_file) {
  31.         unlink $pid_file if $j[9] < (time - 90);
  32.         return if -e $pid_file;
  33.     }
  34.     unless (my $pid = fork) { # task manager daemon itself
  35.         my $mask = umask(0333);
  36.         if (open (FILE, "> $pid_file")) {
  37.             print FILE $$;
  38.             close (FILE);
  39.             umask($mask);
  40.         } else {
  41.             program_exit(0);
  42.         }
  43.         $SIG{INT} = sub { unlink "$DCONF->{admin_dir}/data/dtaskman.pid"; program_exit(0); } ;
  44.         $SIG{TERM} = sub { unlink "$DCONF->{admin_dir}/data/dtaskman.pid"; program_exit(0); } ;
  45.         close STDOUT; close STDIN; close STDERR;
  46.         taskman_daemon();
  47.     }
  48.     return;    
  49. }
  50.  
  51. ###
  52. ### taskman_check_process_id
  53. ###
  54. ### Checks to make sure that this is the desired task manager, and if not, exits
  55. ###
  56.  
  57. sub taskman_check_process_id {
  58.     my ($pidfile, $mypid) = @_;
  59.     $mypid = $$ if ! $mypid;
  60.     if (open(FILE, "< $pidfile")) {
  61.         my @file = <FILE>;
  62.         close (FILE);
  63.         program_exit(0) if $mypid != $file[0];
  64.     } else {
  65.         program_exit(0);
  66.     }
  67. }
  68.  
  69. ###
  70. ### taskman_daemon
  71. ###
  72. ### The task manager itself
  73. ###
  74.  
  75. sub taskman_daemon_spawn;
  76.  
  77. sub taskman_daemon {
  78.     my $taskman_dir = join("/", $DCONF->{admin_dir}, "data", "dtaskman");
  79.     my $pid_file = "$DCONF->{admin_dir}/data/dtaskman.pid";
  80.     if (! -e $taskman_dir) {
  81.         mkdir($taskman_dir, oct($DCONF->{perms0777})) || taskman_force_exit();
  82.         chmod(oct($DCONF->{perms0777}), $taskman_dir);
  83.     }
  84.     my $DEBUG_PROC = 1;
  85.     my $iterations = 0;
  86. W:    while (-e $pid_file && $iterations < 100) {
  87.         sleep 1;
  88.         $iterations++;
  89.         my $now = time;
  90.         utime $now, $now, $pid_file;
  91.         taskman_check_process_id($pid_file, $$);
  92.         if (opendir(DIR, $taskman_dir)) {
  93.             my @dir = map {"$taskman_dir/$_"} grep {not /^\.\.?$/} readdir DIR;
  94.             closedir(DIR);
  95. F:            foreach my $file (@dir) {
  96.                 next F if ! -f $file;
  97.                 my $mtime = (stat $file)[9];
  98.                 next F if (12+$mtime) > $now;  # Prevent locking with calling process
  99.                 if ($DEBUG_PROC) {
  100.                     open (STDERR, "> $DCONF->{admin_dir}/data/taskman.err") if $DEBUG_PROC;
  101.                     print STDERR "Starting task manager daemon $$\n" if $DEBUG_PROC;
  102.                     print STDERR "File: $file\n" if $DEBUG_PROC;
  103.                 }
  104.                 if (open(FILE, "< $file")) {
  105.                     my @file = <FILE>;
  106.                     close (FILE);
  107.                     if (unlink $file) {
  108.                         taskman_daemon_spawn sub {
  109.                             my $subroutine = shift @file; chomp $subroutine;
  110.                             my $subfile = shift @file; chomp $subfile;
  111.                             my @args = taskman_unencode_arguments(\@file);
  112.                             if ($DEBUG_PROC) {
  113.                                 dreq("debug");
  114.                                 my $fh = select(STDERR);
  115.                                 print "Subroutine: $subroutine\n";
  116.                                 print "File: $subfile\n";
  117.                                 array_dump(\@args, 0, 'Arguments');
  118.                                 select($fh);
  119.                             }
  120.                             dreq("$subfile");
  121.                             my $sh = \&{ $subroutine };
  122.                             &{ $sh }(@args);
  123.                         };
  124.                     }
  125.                 }
  126.                 close (STDERR) if $DEBUG_PROC;
  127.                 my $now = time;
  128.                 utime $now, $now, "$DCONF->{admin_dir}/data/dtaskman.pid";
  129.             }
  130.             next W if scalar(@dir);        
  131.         }
  132.         sleep 4;
  133.         if ($DCONF->{pro} && $GLOBAL_OPTIONS->{discus_schedman} && ! -e "$DCONF->{admin_dir}/data/schedule.pid") {
  134.             if ($GLOBAL_OPTIONS->{maintenance} == 0) {
  135.                 taskman_create_job("schedule_daemon_start", "schedule-PRO", undef);
  136.             }
  137.         }
  138.     }
  139.     program_exit(0) if ! -e "$DCONF->{admin_dir}/data/dtaskman.pid";
  140.     unlink "$DCONF->{admin_dir}/data/dtaskman.pid";
  141.     taskman_init();
  142.     program_exit(0);
  143. }
  144.  
  145. ###
  146. ### taskman_daemon_spawn
  147. ###
  148. ### Creates a child process to perform a task
  149. ###
  150.  
  151. sub taskman_daemon_spawn {
  152.     my $coderef = shift;
  153.     unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') { 
  154.         return undef;
  155.     }
  156.     my $pid;
  157.     if (!defined($pid = fork)) {
  158.         log_error("dtaskman.pl", "taskman_daemon_spawn", "cannot fork: $!");
  159.         return undef;
  160.     } elsif ($pid) {
  161.         wait;
  162.         return;
  163.     }
  164.     program_exit(&$coderef());
  165. }
  166.  
  167. ###
  168. ### taskman_create_job
  169. ###
  170. ### Creates a job for the task manager to do later
  171. ###
  172.  
  173. sub taskman_create_job {
  174.     my ($subroutine, $subfile, $arg_list) = @_;
  175.     my $taskman_dir = join("/", $DCONF->{admin_dir}, "data", "dtaskman");
  176.     my $jobnum = join("", substr(time, length(time) - 4, 4), substr($$, 0, 4)); $jobnum =~ s/\D//g;
  177.     $jobnum += int(rand(10)) while -r "$taskman_dir/$jobnum.txt";
  178.     open (JOBFILE, "> $taskman_dir/$jobnum.txt");
  179.     print JOBFILE "$subroutine\n";
  180.     print JOBFILE "$subfile\n";
  181.     my @args = taskman_encode_arguments(@{ $arg_list });
  182.     foreach my $x (@args) {
  183.         print JOBFILE $x, "\n";
  184.     }
  185.     close (JOBFILE);
  186.     return $jobnum;    
  187. }
  188.  
  189. ###
  190. ### taskman_encode_arguments
  191. ###
  192. ### Encodes subroutine arguments
  193. ###
  194.  
  195. sub taskman_encode_arguments {
  196.     dreq("storage");
  197.     return storage_encode_arguments(@_);
  198. }
  199.  
  200. ###
  201. ### taskman_unencode_arguments
  202. ###
  203. ### Unencodes an argument list
  204. ###
  205.  
  206. sub taskman_unencode_arguments {
  207.     dreq("storage");
  208.     return storage_unencode_arguments(@_);
  209. }
  210.  
  211. ###
  212. ### taskman_unencode_hash
  213. ###
  214. ### Transforms an encoded hash into an unencoded hash
  215. ###
  216.  
  217. sub taskman_unencode_hash {
  218.     dreq("storage");
  219.     return storage_unencode_hash(@_);
  220. }
  221.  
  222. ###
  223. ### taskman_unencode_array
  224. ###
  225. ### Transforms an encoded array into an unencoded array
  226. ###
  227.  
  228. sub taskman_unencode_array {
  229.     dreq("storage");
  230.     return storage_unencode_array (@_);
  231. }
  232.  
  233. ###
  234. ### taskman_encode_hash
  235. ###
  236. ### Transforms an unencoded hash into an encoded hash
  237. ###
  238.  
  239. sub taskman_encode_hash {
  240.     dreq("storage");
  241.     return storage_encode_hash (@_);
  242. }
  243.  
  244. ###
  245. ### taskman_encode_array
  246. ###
  247. ### Transforms an unencoded array into an encoded array
  248. ###
  249.  
  250. sub taskman_encode_array {
  251.     dreq("storage");
  252.     return taskman_encode_array(@_);
  253. }
  254.  
  255. ###
  256. ### taskman_force_exit
  257. ###
  258. ### Abnormal exists from the task manager
  259. ###
  260.  
  261. sub taskman_force_exit {
  262.     unlink "$DCONF->{admin_dir}/data/dtaskman.pid";
  263.     program_exit(0);
  264. }
  265.  
  266. 1;
  267.