On 18/03/2013 13:25, Alex Peshkoff wrote:
> On 03/18/13 17:35, Adriano dos Santos Fernandes wrote:
>> MyStatusImpl status;    // inline
>> apiFunction(&status);   // status methods are called only if a error is
>> throw
>> status.check()    // inline
>>
>> So I have doubts about the provider manner of calling init.
> Old, well-known conflict between performance and flexibility :)
> But OK, let's go in this direction if nobody objects. In fact 99, 9999% 
> of that inits will be useless.
> What's not good is that we add one more 'hidden' difference with old api 
> and in an aspect where it was rather clear.
> And we have some troubles when we plan to analyze returned IStatus in 
> cases when we pass already existing interface to somebody else. Not 
> typical case, but if we say that in case of no-error status is not 
> changed we will have to add own status variable and probably copy it 
> back to passed to us interface. Telling that on no-error state of 
> IStatus is implementation-defined does not look like good idea.

Then our implementations should never call a user status get method
directly, as it may contain garbage (not cleared).

We may write a delegate that inline initialize cleared and delegates set
to the caller status.

> Therefore great desire to solve first what to do with warnings 
> (how to store them in IStatus better), next change engine code (where 
> that warnings arrive).
I do not think the problem with warnings is the way it's stored in
status vector. The main problem is that we can't carry then without a
IStatus, while we can carry exceptions without it (converting and
throwing, catching and converting).

>> Yes, but have status.check() and try { ... } catch { ... stuff ... }
>> everywhere is neither elegant.
> I talk first of all not about elegance, but about having debuggable 
> code. If (for example) boost becomes standard de facto and therefore 
> debiggers are learned to take it into an account, I will certainly agree 
> with using macros in such cases.
In the case of interface generation with macros, there is possibility to
preprocess interface headers first and write then to disk. Kinda of IDL
compiler, but may be done with the preprocessor.

It will have generated code to step into, but not different than if you
manually write them.


>
>> And this is what I saw it's required to support, but do you think the
>> current code allows it?
> As far as I know - yes, it does.
I'm not sure I understand you. More below.

>>>> , as the engines will call a yvalve function
>>>> (fb_get_master) who cannot be guessed from what library it must be
>>>> called. IMO, IMaster should being passed as parameters, and not like
>>>> current.
>>>           PluginEntrypoint* startModule;
>>>           if (module->findSymbol(STRINGIZE(FB_PLUGIN_ENTRY_POINT),
>>> startModule))
>>>           {
>>>               startModule(masterInterface);
>>>
>>> Removed some code to make it visible better that IMaster is passed here
>>> as a parameter to plugin module at startup. If you prefer another form
>>> ("not like current"), please suggest.
>> Usage of CachedMasterInterface in jrd.cpp seems correct.
>>
>> But what about this code?
>>
>> IMaster* CachedMasterInterface::getMasterInterface()
>> {
>>      if (!cached)
>>      {
>>          cached = fb_get_master_interface();
>>      }
>>      return cached;
>> }
>>
>> If you have 3.0 and 3.1 engines loaded in memory, each one correctly
>> loaded by different client/y-valve libraries, how do you think when this
>> code is called inside the engine, it will get the correct IMaster?
> Yes. It will get IMaster from yvalve which loaded an engine.

If you have:
/opt/app/fb3.0/lib/fbclient.so loads /opt/app/fb3.0/lib/fbengine30.so
/opt/app/fb3.1/lib/fbclient.so loads /opt/app/fb3.1/lib/fbengine31.so

Do you think fb_get_master_interface() called from fbengine30.so will
call /opt/app/fb3.0/lib/fbclient.so and /opt/app/fb3.1/lib/fbengine31.so
will call /opt/app/fb3.1/lib/fbclient.so?

If true, that's news for me that things just works automatically as
there. And what about Windows DLLs? And others posix (HP-UX, AIX) platforms?


>> Many places calls MasterInterfacePtr, PluginManagerInterfacePtr and
>> others that will not work correct.
> The question is what is called correct. In plugins there will always be 
> present cached IMaster. In external code (currently it's only remote 
> server if I'm not missing something) fb_get_master_interface() from the 
> library loaded at startup time top resolve external references will be 
> used. On my mind that's correct.
I'm not sure I understand you in relate to doubts expressed above.

> If some plugins do not get access to particular engine due to badly 
> configured system - hmm, sooner of all people should not load multiple 
> clients if (for example) they want to have in external routines 
> cross-database calls to databases with other ODS.
Neither here.

>>>> - Checkouts/Checkins:
>>>>
>>>> The interaction of checkouts and checkins in the engine is not clear in
>>>> regard to plugins. AFAIK this was not necessary (external engines first
>>>> implementation work without some of them introduced later), cause the
>>>> reentrant locks still work without them. If it's not necessary, why do
>>>> some of them (checkouts) were introduced?
>>> Can you be more specific here? What checkouts do you not like?
>> It's not about I like/dislike. For example, before I implemented
>> IMetadataBuilder, your recommendation was that user would need to
>> implement IMessageMetadata getter methods, and with the current API this
>> is still possible. But you do not implement IMessageMetadata getter
>> methods with checkouts. How user must know if he can enter in the engine
>> from this methods or not? If he does, it will happen a checkin without a
>> checkout.
>>
>> This is what I mean. And if it works, why the checkout is necessary on
>> the more obvious paths?
> Now I understand a problem. Well, we even do not need new 
> IMessageMetadata - suppose it's possible to find a place where IStatus 
> methods are called w/o checkout. And engine's behavior will be 
> definitely not good. I think that for interfaces like mentioned 
> IMessageMetadata (moreover - IStatus) it's better to prohibit API calls. 
> With check certainly. Not good that this check itself requires 
> resources. May be better ideas? Checkout when we are going to use such 
> methods? For IStatus for example it's almost not needed - it's set() 
> must be called only when receiving exceptions from inner layers. Calls 
> to IMessageMetadata() methods are also well grouped together.
Seems this prohibitions need to be documented. Also, some (most of)
external code may not use another thread and call interface methods that
enters in the engine.

>>>>    What if a checked-out plugin
>>>> codes calls a non-provider API function that enters deep in the engine?
>>>> This problems is also related with the tdbb still being used.
>>> Do we still have non-provider API functions that may enter deep in the
>>> engine? This definitely worth solving.
>> The important word here is "may", as explained above. It's plugin writer
>> who decide things. We must then define what's is possible, impossible
>> (error conditions) or undefined behaviours.
> Forget it. I just did not understand what means function that enters 
> deep in the engine here.
>
>>>> - Pools x refcounters:
>>>>
>>>> I personally hate to use pools (and yes, I hate the refcounters too) and
>>>> the cost of carrying them, but at least it was consistent in usage. But
>>>> now, refcounted objects are created in the global pool, while it's
>>>> internal objects may or may not be in the same pool.
>>> Yes. And that's not a problem, though seems to be so at the first
>>> glance. With refcounted object in global pool we provide stable pointer
>>> to the outside world (and internal async calls: logically they do not
>>> differ much from external API calls), that mini-object checks presence
>>> of BIG internal object (which may be created in another pool), and if
>>> present - calls it. Nothing bad happens.
>> Another thing I want to be solved is code like that:
>>
>> RefPtr x(functionThatReturnRefWith1Count());
>> if (x)
>>      x.release();
>> // use x
>>
>> This is very ugly. But maybe a simple second parameter in RefPtr may
>> solve it.
> Yes, worth thinking and doing.
>
>>>> We cannot use the std C++ library. We rewrote thread
>>>> support,
>>> Hmm...
>>> Something new for me. There was a win-only code which solved
>>> response-time problems with old thread manager. They were pre-fb3, but
>>> both are gone in fb3.
>>> Is it degradation?
>>>
>>>> we rewrote multi-thread sync. objects and many things available.
>>> As long as existing standard objects satisfy our requirements we use
>>> them. But what to do if we need something more?
>> But sometimes looks that Firebird is the only software who push the
>> limits. I think in many cases existing boost/std libraries may solve our
>> problems like they solves everyone else problems.
> Don't know. Probably.
> If we already have working solution I do not volunteer to look for 
> presence of analogue...
> One think may be said for sure - I do not remember cases when we added 
> own objects instead of working for us standard one.
But another way to look at it is: I need something. Does it have been
implemented by someone good? No, then I write it.

But we're doing in 20+ years: I need something. I need to write it.

And IMHO, this does not always make sense.

>>>> We cannot write C++ code usable internally in Firebird and available to
>>>> our C++ users.
>>> And what about Delphi users who need same fucntionality? [Almost sure
>>> that number of them > number of C++ users. ]
>> But Firebird is coded in C++, and my point was to externalize our things
>> that makes usage of API (in C++) easy. But if this code depends on
>> entire Firebird common library and does not uses standard C++
>> facilities, no body would want to integrate our code in their projects.
> API should not be oriented on how internals are coded, including what 
> language is used for it.
Sure, but if our C++ interface return pointers, why our code should not
support this pointers with std/boost C++ smart pointers?

If I need to create a small class to better support the API usage (like
before your new metadata, we needed blr generation and storage), this
class could not use std containers and would need full FB common library.

>>>> We have our strings, we have our exceptions and everyone
>>>> should adapt to it.
>>> That wonderful std::string missing even trivial trim() function? No, please!
>>> Well, I do not remember details why we stopped to use std::exception.
>>> Something like it was suggested by Jim many years ago.
> Remembered main problem. For correct use of std::exception RTTI was 
> needed, which seemd to be a problem for some OS (Mac?).
But what!? If these guys this not fixed this yet, their are not serious
and we should not care about them. Actually, by download statistics I
may say they are irrelevant but requires a lot of development resources
and constrained choices.

> With all this new++ technologies the main question comes - what does 
> project win with such code rework? Except possibility of problems on 
> some platforms :( May be I miss some obvious pluses...
>
The other way of asking is, what we really win not adopting good OS
projects and constraining to old tools?


Adriano


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to