473,378 Members | 1,417 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

Singleton class fails on reboot


Hi,

I am writing a windows service. The code runs fine when I start the
service when my machine is running but
it fails to start automatically when the machine reboots. The code
bombs out when it reaches code that tries to access
a singleton class. This is the code.

void ClientLogging::initClientErrorLog(InstallationInfo install)
{

// next line fails on a reboot
string szLogLevel =
ConfigManager::Instance().getConfigMgrValue("LOG_L EVEL");

Logging::Instance().Initialize("IseeCltLog");

Logging::LogLevel severity =
Logging::Instance().toSeverity(szLogLevel);

m_pFileLogAppender = new FileLogAppender(severity, logFile); //this
line fails on reboot
if(false == Logging::Instance().addAppender(m_pFileLogAppender ))
{

}

}

The strange thing is ClientLogging is also a singleton, the first one
that is called, and this works fine.
This is called using:

ClientLogging::Instance().initClientErrorLog(insta ll);

But it is inside this that the problems arise, on the line as seen
above

string szLogLevel =
ConfigManager::Instance().getConfigMgrValue("LOG_L EVEL");

The code just terminates.
Is there anything I can do to prevent this, any pragma.
Could this be because I initialize static variables.
Your help would be greatly appreciated.
Enda

Jul 5 '06 #1
12 1852

ke****************@yahoo.co.uk wrote:
Hi,

I am writing a windows service. The code runs fine when I start the
service when my machine is running but
it fails to start automatically when the machine reboots. The code
bombs out when it reaches code that tries to access
a singleton class. This is the code.

void ClientLogging::initClientErrorLog(InstallationInfo install)
{

// next line fails on a reboot
string szLogLevel =
ConfigManager::Instance().getConfigMgrValue("LOG_L EVEL");

Logging::Instance().Initialize("IseeCltLog");

Logging::LogLevel severity =
Logging::Instance().toSeverity(szLogLevel);

m_pFileLogAppender = new FileLogAppender(severity, logFile); //this
line fails on reboot
if(false == Logging::Instance().addAppender(m_pFileLogAppender ))
{

}

}

The strange thing is ClientLogging is also a singleton, the first one
that is called, and this works fine.
This is called using:

ClientLogging::Instance().initClientErrorLog(insta ll);

But it is inside this that the problems arise, on the line as seen
above

string szLogLevel =
ConfigManager::Instance().getConfigMgrValue("LOG_L EVEL");

The code just terminates.
Is there anything I can do to prevent this, any pragma.
Could this be because I initialize static variables.
Your help would be greatly appreciated.
Enda
Your second flagged failure involves file access. I'm guessing your
first flagged failure also involves file access (maybe reading a config
file?)

I can only think of one thing - a security issue: the user your service
is starting as after a reboot is not the same user as you are when you
start it manually, and the former doesn't have access rights to the
required files?

But I'm probably wrong...

I think the singleton thing is a red herring.

Doug

Jul 5 '06 #2

<ke****************@yahoo.co.ukwrote in message
news:11*********************@b68g2000cwa.googlegro ups.com...
>
Hi,

I am writing a windows service. The code runs fine when I start the
service when my machine is running but
it fails to start automatically when the machine reboots. The code
bombs out when it reaches code that tries to access
a singleton class. This is the code.

void ClientLogging::initClientErrorLog(InstallationInfo install)
{

// next line fails on a reboot
string szLogLevel =
ConfigManager::Instance().getConfigMgrValue("LOG_L EVEL");

Logging::Instance().Initialize("IseeCltLog");

Logging::LogLevel severity =
Logging::Instance().toSeverity(szLogLevel);

m_pFileLogAppender = new FileLogAppender(severity, logFile); //this
line fails on reboot
if(false == Logging::Instance().addAppender(m_pFileLogAppender ))
{

}

}

The strange thing is ClientLogging is also a singleton, the first one
that is called, and this works fine.
This is called using:

ClientLogging::Instance().initClientErrorLog(insta ll);

But it is inside this that the problems arise, on the line as seen
above

string szLogLevel =
ConfigManager::Instance().getConfigMgrValue("LOG_L EVEL");

The code just terminates.
Is there anything I can do to prevent this, any pragma.
Could this be because I initialize static variables.
We can't tell from the little code you've shown. I'd suspect that the
problem has to do with how you're using or configuring the service (e.g.,
permissions, as Doug suggests). It could also have to do with the order of
initialization of static variables, but you haven't shown those variables or
how they're initialized.

I'd suggest you ask in a windows newsgroup with any windows-related
questions.

But if you think this is really a C++ _language_ question, you could try to
temporarily change the code so that your functions don't do anything
specific to Windows, and see if you still get the same behavior. Then post
the code (with the static variables involved and how they're initialized)
here and we can help see if it's a language-related issue.

-Howard

Jul 5 '06 #3
It could also be a service dependency thing. Your service could be dependent
on (say) the RPC service, but if you haven't installed it that way it will
come up first and fail. Of course those other dependent services are
already running when you start yours manually later.
--
Phil Wilson [MVP Windows Installer]
----
<ke****************@yahoo.co.ukwrote in message
news:11*********************@b68g2000cwa.googlegro ups.com...
>
Hi,

I am writing a windows service. The code runs fine when I start the
service when my machine is running but
it fails to start automatically when the machine reboots. The code
bombs out when it reaches code that tries to access
a singleton class. This is the code.

void ClientLogging::initClientErrorLog(InstallationInfo install)
{

// next line fails on a reboot
string szLogLevel =
ConfigManager::Instance().getConfigMgrValue("LOG_L EVEL");

Logging::Instance().Initialize("IseeCltLog");

Logging::LogLevel severity =
Logging::Instance().toSeverity(szLogLevel);

m_pFileLogAppender = new FileLogAppender(severity, logFile); //this
line fails on reboot
if(false == Logging::Instance().addAppender(m_pFileLogAppender ))
{

}

}

The strange thing is ClientLogging is also a singleton, the first one
that is called, and this works fine.
This is called using:

ClientLogging::Instance().initClientErrorLog(insta ll);

But it is inside this that the problems arise, on the line as seen
above

string szLogLevel =
ConfigManager::Instance().getConfigMgrValue("LOG_L EVEL");

The code just terminates.
Is there anything I can do to prevent this, any pragma.
Could this be because I initialize static variables.
Your help would be greatly appreciated.
Enda

Jul 5 '06 #4

ke****************@yahoo.co.uk wrote:
Hi,

I am writing a windows service. The code runs fine when I start the
service when my machine is running but
it fails to start automatically when the machine reboots. The code
bombs out when it reaches code that tries to access
a singleton class. This is the code.

void ClientLogging::initClientErrorLog(InstallationInfo install)
{

// next line fails on a reboot
string szLogLevel =
ConfigManager::Instance().getConfigMgrValue("LOG_L EVEL");

Logging::Instance().Initialize("IseeCltLog");

Logging::LogLevel severity =
Logging::Instance().toSeverity(szLogLevel);

m_pFileLogAppender = new FileLogAppender(severity, logFile); //this
line fails on reboot
if(false == Logging::Instance().addAppender(m_pFileLogAppender ))
{

}

}

The strange thing is ClientLogging is also a singleton, the first one
that is called, and this works fine.
This is called using:

ClientLogging::Instance().initClientErrorLog(insta ll);

But it is inside this that the problems arise, on the line as seen
above

string szLogLevel =
ConfigManager::Instance().getConfigMgrValue("LOG_L EVEL");

The code just terminates.
Is there anything I can do to prevent this, any pragma.
Could this be because I initialize static variables.
Your help would be greatly appreciated.
Your singletons should be created inside a static member function as a
local static variable.
That's the only way to garantee, that your singleton will be created in
a just-in-time order.
If you create your singleton as a global variable or a static member
variable, there's no way to garantee it will be initialized when it's
first used by another global object (like another singleton).
Example:
foo& foo::Instance() //Where Instance is declared as a static method
{
static foo my_foo;
return my_foo;
}

Jul 6 '06 #5
Hi,

Thanks for all your replies.

I do think it is a singleton issue.

When I comment out the code above the service starts correctly. The
service is already dependent on the RPC service. I have been through a
microsoft support case to verify this.

But I would like to hear more about the last reply from Axter.

This is my current Instance() function.

Foo& Foo::Instance(void)
{
if(_theInstance == 0)
_theInstance = new Foo();
return *_theInstance;
}

How do I change this to incorporate your last advice.
Enda
Axter wrote:
ke****************@yahoo.co.uk wrote:
Hi,

I am writing a windows service. The code runs fine when I start the
service when my machine is running but
it fails to start automatically when the machine reboots. The code
bombs out when it reaches code that tries to access
a singleton class. This is the code.

void ClientLogging::initClientErrorLog(InstallationInfo install)
{

// next line fails on a reboot
string szLogLevel =
ConfigManager::Instance().getConfigMgrValue("LOG_L EVEL");

Logging::Instance().Initialize("IseeCltLog");

Logging::LogLevel severity =
Logging::Instance().toSeverity(szLogLevel);

m_pFileLogAppender = new FileLogAppender(severity, logFile); //this
line fails on reboot
if(false == Logging::Instance().addAppender(m_pFileLogAppender ))
{

}

}

The strange thing is ClientLogging is also a singleton, the first one
that is called, and this works fine.
This is called using:

ClientLogging::Instance().initClientErrorLog(insta ll);

But it is inside this that the problems arise, on the line as seen
above

string szLogLevel =
ConfigManager::Instance().getConfigMgrValue("LOG_L EVEL");

The code just terminates.
Is there anything I can do to prevent this, any pragma.
Could this be because I initialize static variables.
Your help would be greatly appreciated.

Your singletons should be created inside a static member function as a
local static variable.
That's the only way to garantee, that your singleton will be created in
a just-in-time order.
If you create your singleton as a global variable or a static member
variable, there's no way to garantee it will be initialized when it's
first used by another global object (like another singleton).
Example:
foo& foo::Instance() //Where Instance is declared as a static method
{
static foo my_foo;
return my_foo;
}
Jul 6 '06 #6
* ke****************@yahoo.co.uk:
[top-posting, over-quoting, cross-posting to Windows group]
Please don't top-post in [clc++]; please don't quote irrelevant
material; please don't cross-post post to platform-specific groups.

And please read the [clc++] FAQ before posting to [clc++].

The FAQ has a section about how to post.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 6 '06 #7

Alf P. Steinbach wrote:
* ke****************@yahoo.co.uk:
[top-posting, over-quoting, cross-posting to Windows group]

Please don't top-post in [clc++]; please don't quote irrelevant
material; please don't cross-post post to platform-specific groups.

And please read the [clc++] FAQ before posting to [clc++].

The FAQ has a section about how to post.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Ok,
Sorry about that,

but can someone explain to me how to implement this Just in time
singleton based on my current instance function.

Foo& Foo::Instance(void)
{
if(_theInstance == 0)
_theInstance = new Foo();
return *_theInstance;
}

Enda

Jul 6 '06 #8
ke****************@yahoo.co.uk wrote:
can someone explain to me how to implement this Just in time
singleton based on my current instance function.

Foo& Foo::Instance(void)
{
if(_theInstance == 0)
_theInstance = new Foo();
return *_theInstance;
}
Well, we can't see the rest of your code, but here's a more complete
example:

template<class T>
class Singleton
{
public:
static T& Instance();
private:
// Disabled functions
Singleton();
Singleton( const Singleton& );
Singleton& operator=( const Singleton& );
Singleton* operator&();
~Singleton();
};

template<class T>
T& Singleton<T>::Instance()
{
static T myObject;
return myObject;
}

Which is used as a wrapper like this:

class A
{
public:
void DoSomething();
// ...

private:
// Private constructor/destructor disallows creation
// except by friends.
friend class Singleton<A>;
A();
~A();

// Disabled functions for singleton usage
A( const A& );
A& operator=( const A& );
A* operator&();
};

typedef Singleton<AtheA;

void Foo()
{
theA::Instance().DoSomething();
}

See chapter 6 of _Modern C++ Design_ for more than you ever wanted to
know about templates in C++.

Cheers! --M

Jul 6 '06 #9
mlimber wrote:
See chapter 6 of _Modern C++ Design_ for more than you ever wanted to
know about templates in C++.
^^^^^^^^^

I meant "singletons" not "templates" (although, the latter might also
apply). --M

Jul 6 '06 #10

ke****************@yahoo.co.uk wrote:
Hi,

Thanks for all your replies.

I do think it is a singleton issue.

When I comment out the code above the service starts correctly.
But that could be because both the lines you identify as failing
involve file access.

How about this: try commenting out the body of
ClientLogging::initClientErrorLog() except for a call to
ConfigManager::Instance(), and then comment out any file access code
inside the ctor for ConfigManager.

I'd wager that this will run fine, and both your singletons will be
created just as you expect. (Of course, without your ConfigManager
initialised properly, your program will probably fail to do what it's
supposed to - but it will show you if file access is the issue.)

The method you show of initialising a singleton is probably fine. It's
a lazy method (where no instance will be created if never required),
but in a multithreaded environment this is hard to do efficiently
without locking.

The method of using a static (although it is better if this is a static
class member, rather than a function local static) works (and is
efficient - requiring no locking), but is not lazy and is obviously
only possible if the resources required to create it are available at
runtime (when such globals are usually initialised). (This is also the
situation in which you can get yourself into dependency problems -
which you originally thought [and I guess, still think] you had.)

HTH,
Doug

Jul 6 '06 #11

mlimber wrote:
mlimber wrote:
See chapter 6 of _Modern C++ Design_ for more than you ever wanted to
know about templates in C++.

^^^^^^^^^

I meant "singletons" not "templates" (although, the latter might also
apply). --M

Thanks, I will try it out.

But this is the singleton template I was using, do you see any issues
why this would not start when the machine reboots.
class DLLEXPORT CSingleton
{
public:

// Return A reference to the instance of the CSingleton class.
// If there is no instance of the class yet, one will be created.
static T& Instance()
{
if (m_instance == 0 )
{
if (m_instance == 0)
{
m_instance = new T;

// exit processing function
std::atexit(CSingleton::DestroyInstance);
}
}
return *(CSingleton::m_instance);
};

// Destroys the CSingleton class instance.
// Be aware that all references to the single class instance will be
// invalid after this method has been executed!
static void DestroyInstance()
{
delete m_instance;
m_instance = NULL;
};

protected:

// shield the constructor and destructor to prevent outside sources
// from creating or destroying a CCSingleton instance.

inline explicit CSingleton() { CSingleton::m_instance =
static_cast<T*>(this); }
inline ~CSingleton() { CSingleton::m_instance = 0; }

private:

inline explicit CSingleton(CSingleton const&) {}
inline CSingleton& operator=(CSingleton const&) { return *this; }

private:

static T* m_instance; // CSingleton class instance
};

// static class member initialisation.
//template <typename TT* CSingleton<T>::m_instance = 0;

~Enda

Jul 6 '06 #12

ke****************@yahoo.co.uk wrote:
mlimber wrote:
mlimber wrote:
See chapter 6 of _Modern C++ Design_ for more than you ever wanted to
know about templates in C++.
^^^^^^^^^

I meant "singletons" not "templates" (although, the latter might also
apply). --M


Thanks, I will try it out.

But this is the singleton template I was using, do you see any issues
why this would not start when the machine reboots.
class DLLEXPORT CSingleton
{
public:

// Return A reference to the instance of the CSingleton class.
// If there is no instance of the class yet, one will be created.
static T& Instance()
{
if (m_instance == 0 )
{
if (m_instance == 0)
{
m_instance = new T;

// exit processing function
std::atexit(CSingleton::DestroyInstance);
}
}
return *(CSingleton::m_instance);
};

// Destroys the CSingleton class instance.
// Be aware that all references to the single class instance will be
// invalid after this method has been executed!
static void DestroyInstance()
{
delete m_instance;
m_instance = NULL;
};

protected:

// shield the constructor and destructor to prevent outside sources
// from creating or destroying a CCSingleton instance.

inline explicit CSingleton() { CSingleton::m_instance =
static_cast<T*>(this); }
inline ~CSingleton() { CSingleton::m_instance = 0; }

private:

inline explicit CSingleton(CSingleton const&) {}
inline CSingleton& operator=(CSingleton const&) { return *this; }

private:

static T* m_instance; // CSingleton class instance
};

// static class member initialisation.
//template <typename TT* CSingleton<T>::m_instance = 0;

~Enda
Hiya,

Other than the odd double-if test around mInstance (which won't help
with locking, if that's what it's for), I can't see any reason why this
would give you any problems.

Doug

Jul 9 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Tim Clacy | last post by:
Is there such a thing as a Singleton template that actually saves programming effort? Is it possible to actually use a template to make an arbitrary class a singleton without having to: a)...
7
by: Ethan | last post by:
Hi, I have a class defined as a "Singleton" (Design Pattern). The codes are attached below. My questions are: 1. Does it has mem leak? If no, when did the destructor called? If yes, how can I...
1
by: Franz | last post by:
Hello NG I added a new tracelog class in a existing assebley witch is located in GAC. If I try to access a methode of this new class I'll get an errormeassage like this: Could not load type...
2
by: EvilOldGit | last post by:
In the stuff I've read about multi threaded singleton it seems to assume that creating the Lock is atomic, and various sources, including Sutter go for RAII. { Lock l; if ( ! inst ).... } But...
3
weaknessforcats
by: weaknessforcats | last post by:
Design Pattern: The Singleton Overview Use the Singleton Design Pattern when you want to have only one instance of a class. This single instance must have a single global point of access. That...
3
by: gary.bernstein | last post by:
I want to call a singleton getInstance function to retrieve a templatized object without knowing what types were used to create the singleton object in the first call to getInstance. How can I do...
9
by: Tony Proctor | last post by:
I need to create a process Singleton object for an ASP application, but I'm having some odd issues In my GLOBAL.ASA, I have an <OBJECTelement specifying the relevant ProgID with RUNAT=Server and...
1
by: =?Utf-8?B?QU1lcmNlcg==?= | last post by:
Sorry this is so long winded, but here goes. Following the model of http://msdn2.microsoft.com/en-us/library/system.runtime.remoting.channels.ipc.ipcchannel.aspx I made a remote object using the...
4
by: John Doe | last post by:
Hi, I have a singleton class defined like this : class UIManager : public CSingleton<UIManager>, public CObject { protected: DECLARE_DYNAMIC(UIManager) friend class CSingleton<UIManager>;
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.