Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

COM CoInitializeEx(COINIT_MULTITHREADED) and AfxDAOInit

Posted on 1999-01-25
8
Medium Priority
?
1,695 Views
Last Modified: 2013-11-25
I've following Microsoft's documentation, for dealing with DAO when you have a secured database.  You basically have to initialize Dao yourself with AfxDaoInit(), and then setup to system MDW for access security.

I'm trying to do this in a Out of Process Com server (EXE), that has called CoInitializeEx(COINIT_MULTITHREADED) to provided a multi-threading COM interface.  This server is a singleton.

The problem is that AfxDaoInit() calls CoInitialize() which calls CoInitialize().  Microsoft documents that CoInitialize() simply calls CoInitializeEx(COINIT_APARTMENTTHREADED).

By calling this, it attempts to change the threading model after initialization and returns an error.  This is a documented error condition.

This problem did not show up until I installed NT Service Pack 4, which I guess properly detects the threading model change.

My question is, how does one use Dao within a multi-threaded out of process com server?  The design of the object is thread safe, DOA is only called and used during an initialization process that is run only once.

0
Comment
Question by:rmichels
  • 4
  • 4
8 Comments
 
LVL 15

Expert Comment

by:Tommy Hui
ID: 1185116
You are probably better off served creating a separate thread that calls CoInitialize() and do all of the DAO stuff in there.
0
 
LVL 3

Author Comment

by:rmichels
ID: 1185117
Sorry, but your answer is the crux of the problem.  Once on thread has called CoInitializeEx(), that thread or any other thread cannot call CoInitializeEx() with a different threading model.

In my program, one thread has started the Server and called CoInitializeEx(), another thread has issued a second CoInitialize()..which errors out.
0
 
LVL 15

Accepted Solution

by:
Tommy Hui earned 300 total points
ID: 1185118
"Once on thread has called CoInitializeEx(), that thread or any other thread cannot call CoInitializeEx() with a different threading model."

This is not true. A thread can enter and leave any COM apartment as long as it properly exits an apartment before entering a different one. In a thread, you can call CoInit as many times as possible. Here is a program (designed for VC for simplicity):

#define _WIN32_WINNT 0x400
#include <windows.h>
#include <ole2.h>
#include <tchar.h>
#include <stdio.h>

#pragma comment(lib, "ole32.lib")

int main(int argc, char* argv[])
{
      HRESULT hr;

      hr = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
      if (FAILED(hr))
      {
            _tprintf(_T("CoInit apartment failed 1. \n"));
      }

      // success
      hr = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
      if (FAILED(hr))
      {
            _tprintf(_T("CoInit apartment failed 2. \n"));
      }

      CoUninitialize();

      // Final call to leave apartment
      //
      CoUninitialize();

      // Switch apartments
      //
      hr = CoInitializeEx(0, COINIT_MULTITHREADED);
      if (FAILED(hr))
      {
            _tprintf(_T("CoInit multi failed 1. \n"));
      }

      hr = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
      if (FAILED(hr))
      {
            _tprintf(_T("CoInit apartment failed 3. \n"));
      }

      // Since only CoInit succeeded
      //
      CoUninitialize();

      return 0;
}

If you run this program, you should see the output: CoInit apartment failed 3. The reason is the main thread is trying to switch COM apartments without properly exiting the apartment first.

In your application, you can have the main thread be in one COM apartment and in your second thread be in another COM apartment. While COM does allow this, it takes more effort to get it right. So you can have your main thread do all of its regular stuff and have a secondary thread and initializes DAO with its own apartment.

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Author Comment

by:rmichels
ID: 1185119
While techinically correct, I don't think your answer helps me, but I'll ask for more information.  The COM Server is an Out of Process EXE server.  On it's main startup, it initializes itself to a Multi Threaded server.  Also this com object is a singleton.  One server for many clients.  So the main thread of the EXE has initialized to Multi Threaded.  When a Client comes in and wants to do some processing, it calls AfxDaoInit, which calls CoInitialize().  This client is on a separate thread.  The CoInitializeFails.  

I don't see how I can uninitialize the first Thread, without breaking the COM interface?  The only uninitialize I do, is when the server is exiting.
0
 
LVL 15

Expert Comment

by:Tommy Hui
ID: 1185120
When the client comes into your server, you can create another thread and wait for the thread to finish. The other thread initializes COM to be single apartment and initializes DAO. It can then do your queries and deinitializes DAO and COM and returns. The client thread can then continue executing with the returned data.

0
 
LVL 3

Author Comment

by:rmichels
ID: 1185121
True, your response is correct and I realize design changes can help the problem, but does not answer the more basic question:

My question is, how does one use Dao within a multi-threaded out of process com server?  Any help there?





0
 
LVL 15

Expert Comment

by:Tommy Hui
ID: 1185122
The trouble with DAO is that in MFC, you are stuck to their model. If you install the DAOSDK, you'll find the dbDao classes which are infinitely more flexible. They will let you initialize to different apartments. The DAOSDK is included on your VC++ CDROM.

If you are familiar with the MFC classes, the dbDao classes are really easy to pick up.
0
 
LVL 3

Author Comment

by:rmichels
ID: 1185123
I'll give your latest comment a try.  Thanks for all your comments!


0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
Article by: evilrix
Looking for a way to avoid searching through large data sets for data that doesn't exist? A Bloom Filter might be what you need. This data structure is a probabilistic filter that allows you to avoid unnecessary searches when you know the data defin…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

876 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question