From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,8a402d78988bdf2b X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-12-20 05:40:59 PST Path: archiver1.google.com!news2.google.com!newsfeed2.dallas1.level3.net!news.level3.com!crtntx1-snh1.gtei.net!news.gtei.net!newsfeed1.easynews.com!easynews.com!easynews!cyclone1.gnilink.net!in.100proofnews.com!in.100proofnews.com!npeer.de.kpn-eurorings.net!rz.uni-karlsruhe.de!feed.news.schlund.de!schlund.de!news.online.de!not-for-mail From: "Ekkehard Morgenstern" Newsgroups: comp.lang.ada Subject: Re: [announcement] SYSAPI and SYSSVC for Windows Date: Sat, 20 Dec 2003 14:40:49 +0100 Organization: 1&1 Internet AG Message-ID: References: NNTP-Posting-Host: p508c097c.dip0.t-ipconnect.de Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Trace: online.de 1071927658 23832 80.140.9.124 (20 Dec 2003 13:40:58 GMT) X-Complaints-To: abuse@einsundeins.com NNTP-Posting-Date: Sat, 20 Dec 2003 13:40:58 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1158 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165 Xref: archiver1.google.com comp.lang.ada:3626 Date: 2003-12-20T14:40:49+01:00 List-Id: "Dmitry A. Kazakov" wrote: > The thing I mentioned was a large automation system for a roller > dynamometer. What do you need Windows NT for in this application? You could also use Windows CE or similar, or GNU/Linux, of course, or QNX, which is said to be a real-time OS. > > Why not use message queues and asynchronous I/O internally and stuff? > > It uses all that. The problem is [very simplified] that two threads which > require approximately same number of time quants per second, get it under > NT, while under XP the balance looks like 8/1, causing stalling of a queue. > Boosting the priority of some of the threads solves the problem, although > leaving a feeling of great discomfort. We have no time for any scientific > researches concerning XP, so we are just waiting for the Service Pack 1000, > Longhorn, Devilhoof, whatsoever! (:-)) If you want me to take a look at the source, just e-mail me. I'm sort of an expert for concurrent programming, so I might be able to show you how to do it on 2000 and XP without any performance problems. Normally, when you get a timing dependency, you have a design problem. Windows never had predictable timing, but that's another story, basically you cannot rely on precise timing. And for almost all applications, you don't ever need it if you take some precautions and use the right design. > > However, you must not terminate the process forcefully. Under some > > conditions, the DLL cleanup is not done properly, but this is documented > > well in the Windows API documentation. > > Yes, this is what I mean - better reboot the box, if a process crashes, and > never ever think to use TerminateProcess... Design your application such that it does not depend on DLL cleanup. The most simple way to detect a previous application failure is to write a flag somewhere when the application starts, and clear it, when it exists normally. When the application starts you check whether that flag is set and perform all necessary cleanup that the previous instance of the process failed to achieve. You can use SEH (Structured Exception Handling) to prevent a process from falling into the system exception handler. You can provide your own, and make sure everything is cleaned up before the process exits and gets restarted. > > A desire in a "ReleaseMutexAndWaitForSingleObject" function smells > > like bad multithreading design to me. What is it that you want to achieve > > with that? > > To avoid race conditions. Because, it is c.l.a, it is worth to mention how > Ada did solve this, it introduced the requeue-statement. Race conditions never happen with properly designed multitasking apps. For example, use the Event objects in Windows to signal conditions and avoid circular dependencies between data producers and consumers. Use the new WaitForSingleObjectEx() or WaitForMultipleObjectsEx() functions to put a thread into an alertable wait state. This is required for asynchronous I/O anyway. If you wait on multiple conditions at once, use WaitForMultipleObjectsEx(). If you want to terminate a thread, give it a signal and wait on the thread object for its temination, then close the thread handle. Provide an SEH handler for every thread to avoid falling into the system exception handler. If you implement your own message queues on Windows, use an Event object and a message list (protected by a mutex semaphore). Make the Event object manual-reset. This way a thread can wait for multiple message queues. If a message is to be queued, lock the message list, queue the message, signal the event object and unlock the message list. If a thread receives a message, the wait returns and then the thread locks the message list, consumes all messages and links them into a private message queue, then resets the event object and unlocks the message list. After handling of all signalled message queues, it begins processing the messages in the private queue. All threads should be serving a particular purpose and not be intertwined with some logic. If you have a clean design, it's easy to rule out race conditions. > I meant ADT in the sense of user-defined types. They could be abstract or > not. All languages have problems with that. For example, in Ada you cannot: > > type Handle is private access Object; > private > type Handle is record -- Private implementation of an access type > ... > end record; In C++, you simply define a class class abstract_class { public: virtual ~abstract_class() = 0; virtual void ifc_func1( void ) = 0; ... }; typedef abstract_class* abstract_class_ptr; To implement a type, simpy write class my_type : public abstract_class { public: virtual ~my_type(); virtual void ifc_func1( void ); ... }; typedef my_type* my_type_ptr; To process an object of any type derived from abstract_class, you simply use the abstract_class_ptr: abstract_class_ptr p = ... ; p->ifc_func1(); and the function ifc_func1 of my_type will get called if the pointer points to an object of that type. > > So having exception contracts for subprograms don't really eliminate > > the problems (programmers) in front of the computer! ;) > > Yes, but DbC allows to manage the problems in a better way. If the programmers all know what they're doing, then it's no problem. > Alternatively one could switch to C++ approach, though deriving all > exceptions from the same base. btw, that could be simply implemented into Ada as: type my_exception is new exception with record ... end record; So, exception would just have to be a tagged type. In a subprogram declaration, you could write perhaps: procedure f( ... ) raise my_exception; However, what to do with exceptions raised by the runtime system? You would also have to write then: procedure f( ... ) raise my_exception, Constraint_Error; for example. The compiler could analyse possible locations for constraint errors, etc., and then complain if Constraint_Error etc. are missing from the explicit exception declaration contract. Programmers often underrate the scope of explicit exception contracts. To declare exception type ranges, one could write: xcpt_a : exception; xcpt_b : exception; type my_xcpts is ( xcpt_a, xcpt_b ); or type my_xcpts is ( xcpt_a : exception, xcpt_b : exception ); For the runtime system this could mean, there'd be a new runtime exception range called "runtime_exceptions". Then, in a subprogram contract, you could write: procedure f( ... ) raise my_exception, runtime_exceptions'Range; This would simplify taking account of that. > Work-around is the worst possible thing for an interface. Depends really on how you do it. Normally you don't let work-arounds show up in the interface (in Ada: in the spec). > I learned Ada (83) before C and C++, so I never liked the latter. As for > peculiarities, most of them have a rationale. That's the difference between > Ada and C++. You need to fall in love with C++, blindly, because to like it > rationally, is impossible! (:-)) I don't really like C++, but only for how it forces the programmer to write a lot of code that isn't really necessary, that's just there to satisfy the pecularities of the language. That's true for Ada too, but generally Ada is much shorter than C++. C++ is well-defined also, btw. There's already a number of ISO standards for C and C++, and they fulfill the same purpose as the Ada rationale. Also, Bjarne Stroustrup's C++ books are also valuable when dealing with the language, since he invented it. > > Hah, you just need to "downgrade" your design a bit and make it simpler, > > not as fancy as you would with C++, and boom you get along well with Ada. > > :) > > In fact, it is the opposite. Ada's approach to OO is much more advanced and > consistent than C++'s one. So one need to downgrade switching to C++. Ada 95 is a simple, light-weight programming language compared to C++. C++ provides almost any OO facility that can be thought of, and hence offers much more OO constructs than Ada. Plus, it's not as limited. However, sometimes you don't want to use an elaborate OO design, because you have to write a lot of extra code just to implement all your class hierarchies. I've not completed my Ada studies yet, and I'm still learning, but from what I've seen, OO programming is very restricted when compared to C++. However, this must not necessarily be bad. For example, in my SYSSVC package, I've used procedures of the form type T is limited private; procedure f( O : in out T ); However, when T has a field that I need to take the address of within the procedure f(), it isn't possible. I tried various things and ended up with using an access value: type T is limited private; type T_Ptr is access T; procedure f( O : in T_Ptr ); Then it was possible to create an access to a member of T within the procedure. This struck me as weird. Can you explain that?