#1 General Discussions & Feedback » Forum going down » 2019-03-24 14:17:24

sascha
Replies: 0

Hi,

this forum will stop operating on 2019-05-09.

All discussions, feedback, bug reports etc. will be centrally handled on GitHub. Please use the CppMicroServices issues page for asking questions.

Thanks everybody for contributing to this forum. If you want to retain your old posts or save previous discussions, retrieve them before the 9th of May 2019.

Sascha

#2 Re: General Discussions & Feedback » Messaging between modules » 2015-06-25 17:35:58

Hi Sebastian,

your are right, there is no Event Admin implementation for CppMicroServices available. Currently, modules can communicate with each other only via custom services (except for the classic code sharing via linked modules, of course).

The CTK Plugin Framework contains an Event Admin implementation for both Qt4 and Qt5. For CppMicroServices, I once thought about taking the CTK Event Admin code and replacing the Qt bits by standard C++ plus a small threading library (e.g. tinythread) for cross-platform threading and synchronization support. However, I currently do not have resources left for doing so myself. Contributions are of course welcome :-)

#3 Re: General Discussions & Feedback » Is it alright to publish CppMicroServices on Biicode? » 2015-06-01 06:59:31

Hi,

the test assumes that default line endings are present in the test data and the appveyor git clone does seem to work with autocrlf=input by default. I would suggest to try and change the autocrlf setting in the appveyor config file to true as suggested here: http://help.appveyor.com/discussions/pr … t_35102707

Are you otherwise satisfied with your PR so far? If yes, I would start adding some remarks on GitHub.

Thanks!

#4 Re: General Discussions & Feedback » Discover module references » 2015-04-24 06:50:58

Hi,

in general, no.

The CppMicroServices library tracks only service usages but this requires clients to consistently use getService / ungetService calls.

Static library dependencies (when modules depend on exported symbols of other modules during link time) could be determined at runtime with some effort but it gets really complicated when libraries use dlopen and dlsym calls themselves. In the context of module unloading with CppMicroServices, you could make your life easier by only trying to unload modules which act as pure "providers", e.g. they only register services and don't export any symbols at all. By using hidden visibility (when using ELF shared libraries) and not exporting any symbols, other libraries cannot link to the module or discover symbols at runtime with dlsym. The registered service implementations can be used by other modules and the dynamics of the CppMicroServices library ensure that clients get notified about the service withdrawal when you unload the "provider module" (which should be possible at any point in time).

- Sascha

#5 Re: General Discussions & Feedback » Is it alright to publish CppMicroServices on Biicode? » 2015-02-21 13:39:42

Hi Azriel,

thanks a lot for the effort you put into this, it is highly appreciated. I have been very busy the last weeks so sorry for getting back to you so late.

I will look through your branch in detail the next week and probably get back to you with a few questions.

Thanks,
Sascha

#6 Re: General Discussions & Feedback » Help with Example projects » 2015-01-19 02:33:35

Hi Tom,

thank you for your interest in CppMicroServices!

You are right that in theory, using interfaces does not mean link-time dependency - where interface is typically defined to represent a class with only pure virtual functions.

In the discussion above, I tried to explain why the dictionary example might contain link-time dependencies - it depends on the platform and compiler optimization level because the interface contains an out-of-line virtual destructor (this is needed for correct dynamic_cast behavior with older gcc compilers).

Best,
Sascha

#7 Re: Feature Requests » Querying module properties without loading the module » 2014-12-19 00:52:51

WayneBailey wrote:

Having a module’s properties accessible without loading the module, allows a client to access data with little computational overhead. Of course, this could be accomplished through the embedded resource feature provided by C++ Micro Services. However, the name-value pair interface provided by the concept of module properties makes accessing date more convenient and amenable to other property related features such as filtering.

I completely agree and this is in principle already possible in the current development branch.

WayneBailey wrote:

Two possible uses are data only modules and determining if a module should be loaded. The ReqCap model addresses the latter. Capabilities are simply properties and requirements are simply filters on those properties. Of course, the ReqCap model may layer on additional semantic behaviors, but underneath it’s simply employing properties and filters. Bottom-line, it’s great to use the ReqCap model to stay consistent with OSGi, but it’s also nice to expose the underlying module properties and filtering of those properties for other uses.

Right. So if I understood you correctly, you would still like to see a mechanism which allows for filtering on module properties outside of the ReqCap model. I think the ResolverHook would provide such a mechanism which I was planning to implement as well. This would allow client code to reduce the set of modules being resolved (providing access the Module instance and hence its properties), which would happen e.g. during auto-loading and hence effectively removing certain modules from the resolution process.

#8 Re: General Discussions & Feedback » Management of shared objects. » 2014-12-15 23:11:19

Correct! ServiceObjects::GetService() can be used for all service scopes (singleton, module, and prototype) and will do the "right thing" (using ModuleContext::GetService() with a PrototypeScope will "downgrade" the scope to "module"). But you can also query the service scope of a ServiceReference<> object by looking at its SERVICE_SCOPE property.

Let me know if you run into more issues!

- Sascha

#9 Re: Feature Requests » Querying module properties without loading the module » 2014-12-15 23:03:27

I like the idea in general but need to think more about the issues involved. Do you have a special use case in mind?

In the recent OSGi specs, there is a generic ReqCap model (requirements / capabilities) which I have been looking at and I am wondering if that would also "solve" our use cases. With such a mechanism, modules (auto-loaded or normal modules) would require specific capabilities in order to be resolved and these requirements would be matched by the framework against other installed libraries (or the framework itself, which could be configured with a certain set of capabilities). If the reqs are not met, the module would not be resolved and not be loaded at all.

Looking forward to your comments.

#10 Re: General Discussions & Feedback » Management of shared objects. » 2014-12-15 22:56:03

The PrototypeServiceFactory::GetService() documentation reads

  The framework invokes this method for each caller requesting a service object using ServiceObjects::GetService().

So every call to ServiceObjects::GetService() will create a new instance (if the factory actually creates a new one). If you would use the ServiceFactory class instead (when registering a service), every module would get a different instance, but GetService() calls from the same module will return a cached instance.

#11 Re: General Discussions & Feedback » Management of shared objects. » 2014-12-15 03:47:08

Hi,

If I understood your scenario correctly, your service objects act as factories and create new objects on demand. Users of these created objects would need to track the life-time of the module providing the service object to avoid accessing code via the created object which has already been un-loaded.

A common solution I know of would be to re-design the system to not rely on services acting as object factories but instead let the consuming party instantiate self-defined objects or objects which are defined in dependent modules and which rely on functionality provided by one or more service objects. The required service objects are wrapped in a helper class which tracks the life-time of the service and which can be implemented in the same module which provides the service interface(s):

struct IFileProtocol
{
  virtual ~IFileProtocol() {}
  virtual void Foo() = 0;
};

class FileProtocolHandler : public IFileProtocol
{
private:

  us::ServiceTracker<IFileProtocol> m_FileProtocolTracker;

public:

  FileProtocolHandler(us::ModuleContext* context, /* service props if needed */)
   : m_FileProtocolTracker(context)
  {
    m_FileProtocolTracker.Open();
  }

  // IFileProtocol interface
  void Foo()
  {
    if(IFileProtocol* fileProto = m_FileProtocolTracker.GetService())
    {
      return fileProto->Foo();
    }
    else
    {
      // fallback / warning msg / etc
    }
  }
};

The intenral tracker takes care of listening to the appropriate service life-cycle events and returns NULL if the service has been withdrawn. If there is still need for a "object factory service", you may consider using the prototype scope feature. Instances returned by a PrototypeServiceFactory which are supposed to be long-living objects still need to be "monitored", which could be achieved by a helper class similar to the one above which again uses a service tracker to be notified when the service was unregistered (which happens on module unloading):

struct IView
{
  virtual ~IView() {}
  virtual void Foo() = 0;
}

class ViewHandler : public IView, private ServiceTracker<IView>
{
private:

  IView* m_View;

  // overwritten from ServiceTracker
  virtual void RemovedService(const ServiceRefereneType& ref, TrackedType service)
  {
    m_View = NULL;
    ServiceTracker::RemovedService(ref, service);
  }

public:

  ViewHandler(us::ModuleContext* context, const us::ServiceReference<IView>& ref)
   : ServiceTracker(context, ref)
   , m_View(context->GetService(ref))
  {
    this->Open();
  }

  // IView interface
  void Foo()
  {
    if (m_View)
    {
      return m_View->Foo();
    }
    else
    {
      // fallback / error msg / etc
    }
  }
};

- Sascha

#12 Re: Feature Requests » Querying module properties without loading the module » 2014-12-15 02:21:33

Work is currently being done on the state machine for managing state transitions properly. There will also be a change in the initialization code for modules, making it more robust in terms of (static) initialization scenarios. There is not much left but 3.0 won't make it before Chirstmas, I'm afraid. I will post a status updated in mid-January about this topic.

#13 Re: General Discussions & Feedback » Is it alright to publish CppMicroServices on Biicode? » 2014-10-27 22:25:52

Thanks a lot for your efforts.

In general, I would suggest to only push releases to Biicode. Although the master contains only "release commits" since some time, I think it is best practice to push the latest release tag. As I am not really familiar with Biicode, I don't know their available policies about versioning though.

In which context are you referring to an "embedded use"? There is an internal CMake variable "US_IS_EMBEDDED" which is used if the source code is embedded in another larger project but this is all done automatically.

The caveat you are mentioning leads me to think about the header file directory layout for CppMicroServices modules. The next release will support multiple modules inside the CppMicroServices repository and header files will typically get installed in

/usr/include/cppmicroservices/core/Module.h
/usr/include/cppmicroservices/shell/ShellService.h
...

So, a user "cppmicroservices" on Biicode could make sense, with the sub-modules representing project names. Again, I don't know if Biicode can handle projects contained in the same repository. But the include directives would look the same in every project using CppMicroServices, irrespective of the fact if it uses Biicode or not.

#14 Re: General Discussions & Feedback » Building service/client modules with different, incompatible compilers » 2014-10-24 00:03:29

Thanks a lot for your input. While it is not on my short-term todo list, I will keep monitoring the CppComponents project and eventually contact its developer. The hourglass pattern you mentioned also looks promising to me (it actually was in my original list of possible approaches).

The approach with declarative services + C-style service interfaces (plus maybe a convenience header-only C++ interface wrapping the C-style interface) could work in a restricted scenario where modules communicate exclusively via service interfaces and do not make any CppMicroServices API calls at all. The declarative services module itself would take care of the service wiring by reading the xml files from the modules and taking care of the CppMicroServices API calls on behalf of the modules. Hence such modules would not have any linker dependencies to the CppMicroServices library (at least not to its C++ API). Dependencies to other modules would only involve the C API for the C-style service interface. Therefore no ABI incompatibilities would exist. Currently, the module initialization code would still force a linker dependency on the CppMicroServices library, but this is going to change soon. So far the theory...

In practice I would still be concerned about different runtimes needed by modules compiled with different compilers. E.g. on Windows, one would get dependencies to different versions of msvcrt.dll, msvcr*.dll, etc. libraries which use different heaps. Correct memory management across module boundaries would have to be enforced (at least in the service interfaces).

#15 Re: General Discussions & Feedback » Is it alright to publish CppMicroServices on Biicode? » 2014-10-23 16:41:44

Hi,

sure, go ahead and publish it. I am not really familiar with biicode, so I don't know how it handles versioning and updating the published project from one release to another.

Would you be willing to look into that and maybe publish new releases?

Thanks!

#16 Re: General Discussions & Feedback » Building service/client modules with different, incompatible compilers » 2014-10-07 18:36:21

I indeed looked through the slides of the C++Now 2014 presentation about CppComponents recently.

You are right that there is no special mechanism in CppMicroServices to achieve some level of improved cross-compiler ABI support. To overcome that, we thought about several different approaches:

  • Just compile everything with the same compiler and flags

  • Use remote services (using IPC or sockets)

  • Decouple clients from the CppMicroServices API using declarative services and use

    • header only service interfaces

    • or C-style service interfaces (structs)

    • or CppComponents based service interfaces

  • Use a hour-glass API design for the CppMicroServices API and interfaces (my personal favourite currently)

Regarding CppComponents, here are my personal thoughts:

  • It is amazing what you can do with plain C++(11) ;-)

  • It depends on C++11 while CppMicroServices is quite conservative and still supports VS 2008 SP1

  • It seems to be quite intrusive on the service interface declaration (haven't looked into that much)

  • There is a proposal about a standardized C++ ABI (subset) by Herb Sutter - this would help a lot but will come with C++17 at the earliest if at all

Btw, the new resources system will allow to embed a compiler specific version string and I am thinking about a light-weight verification mechanism when doing a ModuleContext::Install(...) call in the future. Apart from that, we have always required people to use the same compilers for distributed/partial builds or they are just building everything themselves any way. While obviously not elegant, it is "the way it is" in C++ land.

If you are experimenting with CppComponents, please keep me up-to-date. Any thoughts about advantages/disadvantages of one approach over an other is very welcome as well.

- Sascha

#17 Re: General Discussions & Feedback » Confusion over the behavior of the example code » 2014-10-03 18:26:43

I am almost certain that you are experiencing the differences between link-time dependencies and logical dependencies between modules.

The dictionaryclient module uses the service interface contained in the dictionaryservice module which has an out-of-line virtual destructor. This leads to a link-time dependency on platforms with are "not smart enough" to remove this dependency during link-time optimizations. The note in Example 6 talks about this issue. I have to admit that this is a little detail worth knowing, because its effects are very important.

In the example, the dictionaryservice module provides the service interface (with an out-of-line destructor for consisted behaviour of dynamic casts across shared library boundaries) and an implementation of the service interface. If you decouple these two (by either providing an inline destructor or splitting it into two modules for the interface and the implementation), auto-loading comes in handy to load the implementation module.

I hope this helps,

Sascha

#18 Re: General Discussions & Feedback » Turning off "In AutoLoadModulesFromPath at..." messages » 2014-10-03 17:27:46

You cought me in a good moment...

Have a look at this topic, which talks about a release date at the end of October.

The commits for the log-levels should be self-contained and you could try to cherry-pick ad74798ebfd88208c6d7288c3c22df95bbba6b92 (adds configurable log levels) and / or 488b0c0c3ce7174e6aad471223d3bb3f927ed86a (removes auto-load messages) on top of the 2.1.0 release branch.

Release 3.0 will bring a couple of breaking changes, but nothing severe. It will also have a couple of nice new features though.

#19 Re: General Discussions & Feedback » Turning off "In AutoLoadModulesFromPath at..." messages » 2014-10-03 17:05:16

You run into a missing feature described in Issue 22, which has been implemented in the 22-log-levels branch. This branch is also merged into the development branch already.

To use the new ModuleSettings::SetLogLevel(MsgType) method you obviously would need to use the development branch of CppMicroServices. While this branch is called development, it is tested on Windows, Linux and MacOS and only contains commits where all unit tests pass so it should be quite safe to use. Of course there can and will be API changes in that branch. The branch will be the basis for the 3.0 release.

As a side note, the auto-load messages couldn't be suppressed reliably with log levels because they can happen during application start-up in the static initialization phase, before any user code is executed. So the messages will only be printed in debug mode (a CMake configure option). I am working on another solution to configure the CppMicroServices library from user code, taking into account early initialization issues.

Let me know if you are running into any other issues.

Thanks,
Sascha

#20 Re: Feature Requests » Querying module properties without loading the module » 2014-09-25 15:37:23

Here is a progress update:

The new resources system works well so far on Linux, Windows, and MacOS. However, it implicitly introduces a new life-cycle state for modules - INSTALLED. This has some far-reaching implications and I would like to introduce the new module states with the 3.0 release. Work has started on the ehanced module life-cycle but it will delay the 3.0 release probably until end of October.

#21 Re: Feature Requests » Querying module properties without loading the module » 2014-09-08 23:44:05

I am not aware of any issues on iOS in this regard, but I also didn't try the system on this platform yet. The Mach-O object file format is used both on Mac OS X and iOS and by looking at its documentation, all sections and segments are specified in terms of offsets from the beginning of the file. The current development branch (containing the new resources system) also passes all tests on Mac OS X 10.7 (my test system). It should even work with universal binaries, by adding the blobs at the end of the final universal binary, effectively sharing the resources between all object files for different architectures.

#22 Re: Feature Requests » Querying module properties without loading the module » 2014-08-12 20:54:44

Okay, good to know.

In our case, we have a large code-base developed over more than 10 years which we are gradually moving to a more modular and service oriented architecture. So currently we mostly use module activators replacing static initialization code, the resources system, and at some places the service registry. Service usage is slowly increasing and I fully agree that after a certain threshold, managing service dependencies directly by using the framework API will become unmaintainable. We are just no there yet, but it needs definitely attention!

#23 Re: Feature Requests » Querying module properties without loading the module » 2014-08-12 20:11:44

To be honest, there is no specific due date for version 3.0. Almost all issues except for the resource loading feature have been resolved for 3.0. I did work on the resources system but couldn't find time to finish it yet. I am still aiming for a late September release though, after we got through all the testing for our own product using 3.0 features.

Config Admin is still high on the priority list (we have a few internal projects with requirements for such a service). Declarative Services on the other hand is something I would personally love to have, but its development is not directly driven by any of our current requirements. I also was not planning to couple the service implementations to the 3.0 release to no longer defer it. The development will very likely be based on the 3.0 release and either take place within the CppMicroServices project or get their own repository.

However, I am happy to incorporate external priorities into the planning process as far as possible.

#24 Re: General Discussions & Feedback » Help with Example projects » 2014-06-02 01:31:31

Hi,

thanks for trying CppMicroServices! The eventlistener module does indeed have a bug related to some refactoring which happened before the 2.0 release. I opened GitHub Issue 20 and fixed it in branch 20-event-listener-example-module (based on the 2.1.0 release).

The automatic loading of the dictionaryservice module actually depends on the linker and optimization flags of your particular toolchain. It is not related to the US_ENABLE_AUTOLOADING_SUPPORT configuration. The dictionaryclient module uses the service interface from the dictionaryservice module and hence naively has a link-time dependency to it. However, some linkers (also depending on certain flags and enabled optimization strategies) are able to optimize this link-time dependency away. Hence the dictionaryservice module will not be loaded by the dynamic linker at runtime. The note in Example 6 also tries to explain this a bit.

Hote this helps,

Sascha

#25 Re: General Discussions & Feedback » Usign QtClases as interfaces. » 2014-06-02 00:43:16

Hi, sorry for the long wait - I have been travelling a lot the past weeks.

I checked the usServiceInterface.h header and the US_DECLARE_SERVICE_INTERFACE macro again and you are right: it is not working well together with Qt. Please check out GitHub issue 19 and the commit message for the details. You could use the 19-declare-service-interface-with-qt branch (based on the 2.1.0 release) for your development.

With that branch you should be able to use Q_DECLARE_INTERFACE and Q_INTERFACES in parallel with the CppMicroServices macros. The only small caveat is that you need to use both declare interface macros if you want to use an interface class as a Qt and a micro service interface (as you did with the IPanel class above in the first code block).

Please let me know if there are still some unresolved issues.

Board footer

Powered by FluxBB