updated Signals package

git-svn-id: svn://ultimatepp.org/upp/trunk@588 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
micio 2008-11-01 15:59:09 +00:00
parent 3363baf9f6
commit b0342fe8d3
4 changed files with 171 additions and 1 deletions

View file

@ -17,6 +17,8 @@ void _SignalHandler(int sig, siginfo_t *info, void *v)
// constructor
TSignals::TSignals()
{
// not(yet) stored instance on file
StoredInstance = false;
} // END Constructor TSignals
@ -37,6 +39,11 @@ TSignals::~TSignals()
// empties the map
CallbackMap.Clear();
// if process had stored instance on file, removes it
if(StoredInstance)
FileDelete(CreateLockName());
StoredInstance = false;
} // END Destructor class TSignals
////////////////////////////////////////////////////////////////////////////////////
@ -53,6 +60,17 @@ void TSignals::Dispatch(int sig, siginfo_t *info, void *v)
} // END TSignals::Dispatcher()
////////////////////////////////////////////////////////////////////////////////////
// creates lock file name based on user name, app name and display
String TSignals::CreateLockName(void)
{
if(LockName == "")
LockName = "/tmp/" + Environment().Get("USER") + "_" + GetExeTitle() + "_" + Environment().Get("DISPLAY") + ".lck";
return LockName;
} // END TSignals::CreateLockName()
////////////////////////////////////////////////////////////////////////////////////
// add a signal handler
bool TSignals::Handle(int sig, Callback const &cb)
@ -107,6 +125,76 @@ bool TSignals::Unhandle(int sig)
} // END TSignals::Unhandle()
////////////////////////////////////////////////////////////////////////////////////
// stores process info on filesystem
// allowing other process to communicate with it
bool TSignals::StoreInstance(void)
{
// if already stored, does nothing
if(StoredInstance)
return true;
// first, checks if another instance is running
// if yes returns false (can't store more than 1 instance)
if(IsOtherInstanceRunning())
return false;
// creates lock file
FileOut f(CreateLockName());
// stores current process id on lock file
f.PutLine(AsString(getpid()));
f.Close();
// marks instance as already stored
StoredInstance = true;
// all ok
return true;
} // END TSignals::StoreInstance()
////////////////////////////////////////////////////////////////////////////////////
// checks whether another instance of this process is running
bool TSignals::IsOtherInstanceRunning(void)
{
// if we stored THIS instance, no other is running
if(StoredInstance)
return false;
// otherwise, check the lock file
if(FileExists(CreateLockName()))
return true;
return false;
} // END TSignals::IsOtherInstanceRunning()
////////////////////////////////////////////////////////////////////////////////////
// sends a signal to another process
bool TSignals::Send(int sig, int procId)
{
return (kill(procId, sig) == 0);
} // END TSignals::Send()
////////////////////////////////////////////////////////////////////////////////////
// sends a signal to another running instance of this app
bool TSignals::Send(int sig)
{
// if no other instance running, returns false
if(!IsOtherInstanceRunning())
return false;
// gets pid of other instance
FileIn f(CreateLockName());
int pid = atoi(f.GetLine());
f.Close();
// sends the signal to process
return Send(sig, pid);
} // END TSignals::Send()
////////////////////////////////////////////////////////////////////////////////////
// Global signals access
TSignals &Signals(void)

View file

@ -11,6 +11,11 @@ class TSignals
friend void ::_SignalHandler(int, siginfo_t *, void *);
private:
// flag indicating that the process instance has been stored on file
bool StoredInstance;
String LockName;
// signal/handlers map
ArrayMap<int, Callback> CallbackMap;
@ -20,6 +25,9 @@ class TSignals
// dispatch signals
void Dispatch(int sig, siginfo_t *info, void *v);
// creates lock file name based on user name, app name and display
String CreateLockName(void);
public:
// distruttore
@ -30,7 +38,20 @@ class TSignals
// removes a signal handler
bool Unhandle(int sig);
// stores process info on filesystem
// allowing other process to communicate with it
bool StoreInstance(void);
// checks whether another instance of this process is running
bool IsOtherInstanceRunning(void);
// sends a signal to another process
bool Send(int sig, int procId);
// sends a signal to another running instance of this app
bool Send(int sig);
}; // END Class TSignals
////////////////////////////////////////////////////////////////////////////////////

View file

@ -126,6 +126,13 @@ behaviour:&]
:: [s0; [2 File size limit exceeded]]}}&]
[s0; &]
[s4;%- &]
[s5;:Signals`(void`):%- [_^TSignals^ TSignals]_`&[* Signals]([@(0.0.255) void])&]
[s2; &]
[s2; Returns global TSignals object Used to acceass all package
functions&]
[s2; &]
[s4;%- &]
[s3;%- &]
[s5;:TSignals`:`:Handle`(int`,Callback const`&`):%- [@(0.0.255) bool]_[* Handle]([@(0.0.255) i
nt]_[*@3 sig], [_^Callback^ Callback]_[@(0.0.255) const]_`&[*@3 cb])&]
[s0;%- &]
@ -153,4 +160,44 @@ handle the signal&]
[s2; Example usage:&]
[s0; &]
[s2; -|-|Signals().Unhandle(SIGHUP);&]
[s4;%- &]
[s5;:TSignals`:`:StoreInstance`(void`):%- [@(0.0.255) bool]_[* StoreInstance]([@(0.0.255) v
oid])&]
[s2; &]
[s2; Stores current process info on file allowing check for other
instances&]
[s3;%- &]
[s6; [*/ Return value]-|boolean, true if the call succeeded&]
[s0; &]
[s2; Example usage:&]
[s0; &]
[s2; -|-|Signals().StoreInstance();&]
[s4;%- &]
[s5;:TSignals`:`:IsOtherInstanceRunning`(void`):%- [@(0.0.255) bool]_[* IsOtherInstanceRu
nning]([@(0.0.255) void])&]
[s2; &]
[s2; Checks wether another instance of this app is already running&]
[s3;%- &]
[s6; [*/ Return value]-|boolean, true another instance is running&]
[s0; &]
[s2; Example usage:&]
[s0; &]
[s2; -|-|Signals().IsOtherInstanceRunning();&]
[s3;%- &]
[s4;%- &]
[s5;:TSignals`:`:Send`(int`,int`):%- [@(0.0.255) bool]_[* Send]([@(0.0.255) int]_[*@3 sig],
[@(0.0.255) int]_[*@3 procId])&]
[s2; &]
[s2; Sends a signal to another process&]
[s0; &]
[s2; [%-*@3 sig] ..................................Posix signal number&]
[s2; [%-*@3 procId].............................Process id of target
process&]
[s3; &]
[s4;%- &]
[s5;:TSignals`:`:Send`(int`):%- [@(0.0.255) bool]_[* Send]([@(0.0.255) int]_[*@3 sig])&]
[s2; &]
[s2; Sends a signal to another instance of this application&]
[s0; &]
[s2; [%-*@3 sig] ..................................Posix signal number&]
[s0; ]

View file

@ -39,6 +39,20 @@ TestSignals::TestSignals()
GUI_APP_MAIN
{
// first checks if another app instance is running
if(Signals().IsOtherInstanceRunning())
{
// sends to other instance a SIGHUP signal
Signals().Send(SIGHUP);
// prompt and exit
PromptOK("Another app instance is already running!!!");
return;
}
// ok, no other instance, signals this one
Signals().StoreInstance();
// runs the application
TestSignals().Run();
}