mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
updated Signals package
git-svn-id: svn://ultimatepp.org/upp/trunk@588 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
3363baf9f6
commit
b0342fe8d3
4 changed files with 171 additions and 1 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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; ]
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue