Daemon.pm
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:3k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. #########################################################################
  2. #  OpenKore - Daemon support class
  3. #
  4. #  Copryight (c) 2006 OpenKore Development Team
  5. #
  6. #  This software is open source, licensed under the GNU General Public
  7. #  License, version 2.
  8. #  Basically, this means that you're allowed to modify and distribute
  9. #  this software. However, if you distribute modified versions, you MUST
  10. #  also distribute the source code.
  11. #  See http://www.gnu.org/licenses/gpl.html for the full license.
  12. #########################################################################
  13. ##
  14. # MODULE DESCRIPTION: Daemon support class.
  15. #
  16. # This class allows you to easily write daemons: programs for which there
  17. # should only be a single instance. This class can detect whether an instance
  18. # is already running, and allows you to further initialize the daemon if
  19. # there isn't already another instance running. You can also retrieve
  20. # information about the currently running instance; that information is
  21. # specified by the daemon itself.
  22. package Utils::Daemon;
  23. use strict;
  24. use Exception::Class ('Utils::Daemon::AlreadyRunning' => { fields => ['info'] });
  25. use File::Spec;
  26. use Utils::Exceptions;
  27. use Utils::LockFile;
  28. sub new {
  29. my ($class, $name) = @_;
  30. my %self = (
  31. name => $name,
  32. lock => new Utils::LockFile(tmpfile("$name.lock")),
  33. runlock => new Utils::LockFile(tmpfile("$name.runlock"))
  34. );
  35. return bless %self, $class;
  36. }
  37. sub init {
  38. my ($self, $initFunc) = @_;
  39. my $infoFile = tmpfile("$self->{name}.info");
  40. $self->{lock}->lock();
  41. if ($self->{runlock}->tryLock()) {
  42. # We got the run lock, so the daemon is not running.
  43. my $info;
  44. if ($initFunc) {
  45. $info = $initFunc->();
  46. } else {
  47. $info = {};
  48. }
  49. my $f;
  50. if (open($f, ">", $infoFile)) {
  51. my ($key, $value);
  52. while (($key, $value) = each %{$info}) {
  53. print $f "$key=$valuen";
  54. }
  55. close $f;
  56. $self->{lock}->unlock();
  57. } else {
  58. $self->{runlock}->unlock();
  59. $self->{lock}->unlock();
  60. IOException->throw("Cannot create daemon info file.");
  61. }
  62. } else {
  63. $self->{lock}->unlock();
  64. my $info;
  65. eval {
  66. $info = _readInfo($infoFile);
  67. };
  68. if (!caught('IOException') && $@) {
  69. die $@;
  70. }
  71. Utils::Daemon::AlreadyRunning->throw(
  72. error => "The daemon is already running.",
  73. info  => $info
  74. );
  75. }
  76. }
  77. sub _readInfo {
  78. my ($file) = @_;
  79. my $f;
  80. if (open($f, "<", $file)) {
  81. my %info;
  82. while (!eof($f)) {
  83. my $line = <$f>;
  84. $line =~ s/[rn]//g;
  85. my ($key, $value) = split /=/, $line, 2;
  86. $info{$key} = $value;
  87. }
  88. close $f;
  89. return %info;
  90. } else {
  91. IOException->throw("Cannot open file for reading.");
  92. }
  93. }
  94. sub getInfo {
  95. my ($self) = @_;
  96. my $result;
  97. $self->{lock}->lock();
  98. if (!$self->{runlock}->tryLock()) {
  99. # We didn't get the run lock, so the daemon is running.
  100. my $infoFile = tmpfile("$self->{name}.info");
  101. $result = {};
  102. eval {
  103. $result = _readInfo($infoFile);
  104. };
  105. if (!caught('IOException') && $@) {
  106. my $e = $@;
  107. $self->{lock}->unlock();
  108. die $e;
  109. }
  110. } else {
  111. $self->{runlock}->unlock();
  112. }
  113. $self->{lock}->unlock();
  114. return $result;
  115. }
  116. sub lock {
  117. my ($self) = @_;
  118. $self->{lock}->lock();
  119. }
  120. sub unlock {
  121. my ($self) = @_;
  122. $self->{lock}->lock();
  123. }
  124. sub tmpfile {
  125. my ($basename) = @_;
  126. my $tmpdir;
  127. if ($^O eq 'MSWin32') {
  128. $tmpdir = File::Spec->tmpdir();
  129. } else {
  130. $tmpdir = $ENV{TEMP};
  131. $tmpdir = "/tmp" if (!$tmpdir || ! -d $tmpdir);
  132. }
  133. return File::Spec->catfile($tmpdir, $basename);
  134. }
  135. 1;