I am using a COM dll from a web service.
The COM dll is added as reference. And I am declaring the object as static in Global.asax.
I am creating the COM object in the Application_Start.
I have to call the COM dll interface function in each request.
I am getting exceptions here as memory corruption.I could see the logs that it happens when simultaneous requests come up.
Please let me know what is the best way to do that. How to make it thread safe.?
Try creating a new instance in each request and not use application scope for the object.
If you are accessing it at application scope(eg through Application_Start) you will need to make sure it is safe for multithreading. I don't know how C++ dlls handle threading but you might be able to manage multithreading at the asp.net level.
For example To manage a simple application level counter the code is something like:
Application.Lock();
Application["SomeGlobalCounter"] =
(int)Application["SomeGlobalCounter"] + 1;
Application.UnLock();
For more information you might want to see the MSDN page on Application State.
If the COM object is apartment threaded, COM provides the synchronization to enforce a single execution of a method per thread.
Generally, though, COM should be complaining of multiple threads trying to access an instance of an object using the same pointer shared across threads. Having a static variable holding a pointer to the object is probably a bad idea.
Once the COM object shared library is loaded somewhere (in-proc or out-of-proc) by creating an instance, creation of additional instances per thread should be fairly quick. That is, of course, dependent on what types of things that are being done during object construction.
Related
I have an application that imitates state of a vehicle and uses various plugins to transmit data. Each plugin is loaded dynamically and provides protocol-specific implementation for an interface to send the data. By specification each plugin may be operating concurrently and a sending method may be asynchronous.
I would like to be able to share asio::io_context or asio::thread_pool to utilize those resources allocated by the application (core). Each plugin would use asio::strand if needed. I really wouldn't want plugins to spawn new threads.
To provide compiler independence the API for a plugin is in C, hence I can't pass asio entities just like that.
Is it possible though to expose a context or a thread pool to a dynamically loaded dll which may be compiled with another toolchain?
Maybe via some kind of native handles?
Maybe I could wrap a custom executor?
I didn't find any constructors in the reference which would use native handles, etc.
First what I did (minimum sample will be provided if it's not just me doing something plain stupid):
I have a GUI application that shall support several network interfaces to change content that's displayed in the GUI. The network interfaces are realized as plugins that are dynamically loaded on GUI startup. The GUI application provides a boost::asio::io_service object that it passes via reference to the interfaces so they can use that to build the asynchronous I/O. In the GUI thread this io_service object is than polled to synchronise the network interfaces' access to the content.
The problem now is that the handlers don't get called by the io_service object when it is polled. To narrow this down I implemented only one interface and created the io_service object therein, still calling the poll from the GUI thread and that works.
My question now is: is it possible that there is a general problem with passing the io_service object into DLL functions loaded at runtime?
If the scenario is too unclear, I'll provide a minimum example.
EDIT: I feel really stupid :) Just hacked together a minimum example and that - of course - works like a charm. That pretty much means the problem origins from some other part of the software.
So thanks everyone for their input!
To make this question at least a little bit useful:
Anyone who wants to do something similar (plugins for network synchronized via boost::asio::io_service), you can download the minimum example here.
I would check several options:
* Maybe the object is copied at some point rather than passed by reference; you can make it boost::noncopyable to prevent this from happening.
* Check the return value of poll if it is bigger than 0 some handler was run; if it is 0 the problem is boost think there are no handler.
* Add a test handler in your GUI app to rule out the option it is DLL-related problem.
Happy debugging!
I have got a DLL in which a singleton is defined.
I have got an app which can load multiple instances of this DLL.
The DLL needs a singleton instance per DLL instance, otherwise it will crash.
I observed that there was only one singleton instance for multiple DLL instances. Why? How can I resolved it (if possible, without refactoring the singleton into something else)?
Thanks for any help.
You mentioned that you have multiple instances inside your app, which implies that they all live inside the same process.
Singletons like any other static member are limited to one per application regardless of whether they belong to an object loaded from a DLL etc.
No way without refactoring your code. A DLL is "loaded" into the process space. Any static member defined in there is static for the process (a loaded DLL doesn't have its own memory).
You'll have to write a non-standard "singleton" to get multiple objects.
And if you don't have the sources to the dll, then you must load it in different processes, one "singleton" per process. These could be simple child-processes to your main process that just handle the dll communication part.
Then of course, you must come with some communication scheme between your main process and your child processes, which will depend on how much you are using the dll. Is it just a couple of calls with a lot of data? Or a lot of different calls that differ from run to run?
Generally if you are using the dll to make more than a couple of simple calls it's probably easier to refactor your own code.
From an out-of-process COM object (LocalServer32) can I determine the client process that requested the creation of the object? - to be specific I need to get hold of the client processes command line.
This question arrises because (due to poor standardisation, implementation and support) the potential 3rd party clients of the object have a variety of idiosyncracies which the object needs to workaround.
To do this the object needs to be able to identify its current client.
Extending the interface of the COM object so that the client can identify itself is unfortunately not possible ... or to be more precise the interface can be extended but I won't be able to get the clients to call the extension.
Having looked into this further I suspect the answer is going to be "NO", but by all means tell me I'm wrong.
Using Process Explorer I can see that the parent process for my COM object is an instance of "svchost.exe", and not the client application.
Because COM server processes are shared by all clients of the same AppID, it's not possible to actually get the PID of the client application. As #Anders said, you can use CoImpersonateClient (or, better, call CoGetCallContext and interrogate the resulting IServerSecurity) to find the account and login session of the caller, but you cannot get the process itself.
If you are trying to work around bugs in legacy clients, I would recommend you create a new set of CLSIDs (or IIDs, if you can emulate all the bugs the legacy clients rely on with shims) for new (non-legacy) clients with VERY strict input validation, and implement new features only in these new CLSIDs. Legacy clients stick with their older CLSID, in which you can simply use the existing, legacy implementation (or a bug-for-bug compatible clone).
Maybe CoImpersonateClient()
A legacy c++ applications with sometimes notorious memory leak issues has to be called from a .Net server based windows application. .Net garbage collection times are not determinable and sometime the c++ object are destroyed or not destroyed "on time" producing unpredictable results and generally crashing the c# web app. What is the best way to push the c++ objects onto the garbage collection stack as frequently as possible, but not so often as to remove the .Net reference to the COM object. Keep in mind that the COM objects can spawn sub-objects so the .Net reference count of the COM objects can change with just a function call and not necessarily an instantiation.
As the memory leaks occur and the COM objects are not cleaned up, performance degrades until it is so slow that IIS trips on itself a few times and then crashes. Restarting IIS fixes the issue until the next time. Periodic restarts help, but a busy day can cause this during the business day.
I had to resolve this using .Net 1.1 a couple of years ago. Wondering if someone else had my solution or a better one. This is NOT ASP.NET. It is a .Net dll.
The final result was not completely satisfactory and the web server crashes every few months.
You ask "What is the best way to push the c++ objects onto the garbage collection stack as frequently as possible", but c++ objects are never garbage-collected. Maybe look at it this way...
You have a process that instantiates a bunch of c++ objects. Some of those c++ objects implement COM objects, and their lifetime is therefore managed via AddRef/Release. Some of those COM objects are imported into the .NET world, and are wrapped with an RCW (runtime-callable wrapper). Only the RCW is a .NET object and goes in the garbage-collected heap.
Without any intervention from you, the RCW will eventually be GC'd and when that happens it will do a Release against its underlying COM object. If you want to Release the COM object immediately, without waiting for GC, you can call...
System.Runtime.InteropServices.Marshal.ReleaseComObject
... or even FinalReleaseComObject if you're sure it's what you want.
To get back to your question: you want to know how to delete the c++ objects without releasing the .NET reference to your COM object. Since the c++ objects don't exist in the .NET heap, there's no way to achieve this directly. You could expose a method from your COM object that deletes all its c++ objects, and simply call that from your .NET code. But I guess if it was possible for your COM object to identify all the leaked c++ objects you'd be doing that already.
Hopefully I've explained why there's no way to achieve what you suggest in your question, but there are plenty of tools around to help you find and fix your memory leaks. I suggest using a tool such as LeakDiag (search StackOverflow for it) to find out where your c++ code is leaking memory.
The pragmatic solution, if you're using IIS6 or higher, is to configure application pool recycling. You can tweak the numbers so that processes are killed and restarted before they've ever leaked enough memory to be problematic, and it normally works in such a way that users don't notice any downtime.
Create a COM+ application and put the COM classes you use inside that application. This way all COM objects are instantiated in a separate process. You can periodically release all COM objects and just restart the COM+ application process.