| United States-English |
|
|
|
![]() |
HP 9000 Systems: HP DCE/9000 Application Development Tools for HP-UX 11i Release Note > Chapter 1 HP DCE/9000 Version 1.8 Application Development
Tools for HP-UX 11i Release Note Developing DCE Applications with HP DCE/9000 |
|
This chapter provides information about developing, building, and debugging DCE applications with HP DCE/9000.
When compiling and linking HP DCE applications, note the following:
The following are tips on debugging HP DCE applications. Also see Programming with Threads on HP-UX (B2355-90060) for additional information about debugging HP DCE Applications.
See the README file and server_debug.ksh script in /opt/dce/share/hpexamples/string_conv for information on debugging "dced-started" servers via xdb or dde. If you want to use C++ with standard DCE to create DCE applications, there are some practices you must avoid. Most of these relate to lack of thread-safeness of C++ operations. The following list describes the practices you should avoid. These guidelines apply to HP C++ compiler version A.3.70 and later. By taking these precautions, you should be able to productively use C++ to write DCE applications.
The following are miscellaneous notes on programming with HP DCE. Also see Programming with Threads on HP-UX (B2355-90060). Several features of interest to programmers are not supported at the HP DCE 1.8, including support for the rdaclif routines for ACL managers. You should also be aware of future changes to threads support. For details, see "Features Planned for a Future Release" in Chapter 1 of Planning and Configuring HP DCE 1.8. The Cell Directory Service (CDS) was designed for a specific purpose: to store and retrieve server bindings in a DCE cell. This mission implies numerous assumptions about the volume of information that must be stored and about the types and frequency of access to that information. Performance trade-offs in CDS's usage of memory, disk, cache, the network, and time-outs are optimized to this very specialized purpose. The generality of the application programming interfaces to CDS masks the specificity of this purpose, and gives CDS the appearance of a general-purpose database system. It is not; the optimizations of CDS for its low-volume and weakly-replicated storage, and for retrieval of server bindings in a fairly static name space, are rarely optimal for other purposes. Moreover, other uses of CDS directly compete and interfere with its use and availability as a critical core component of the DCE system. Application developers are frequently tempted to use CDS for the direct storage of information other than server bindings. For example, the developer of a telephone number directory service may consider using CDS to store the information directly. This is a bad idea, as the volume of information could overwhelm the in-memory CDS data structures, and very frequent read accesses could slow CDS performance and lock out DCE server lookup requests. A much better strategy would be to implement a database server designed specifically for the telephone number directory service, and then store the bindings of that server in CDS for lookup by clients. In this way, other uses do not compromise CDS in its intended use as a critical DCE component. The supported programming interfaces to CDS are the RPC Name Service Independent (RPC_NS) interface and the X/Open Directory Service (XDS) interface. The RPC_NS function call prototypes are in the include file /usr/include/dce/rpc.h. The XDS function call prototypes are in the include file / usr/include/xds.h. The RPC_NS interface is the procedural interface used by the core DCE components and most applications. The XDS interface is an object-oriented interface appropriate for use with other X/Open standards such as X.500. Both the RPC_NS and XDS interfaces support many common name space functions, but lack administrative capabilities such as the ability to create and delete directories and manage replication. dcecp is the recommended tool for performing CDS administrative functions such as creating and deleting directories and managing replication. dcecp can be called in a shell script, but is not a programming interface. When creating the directory and its readonly replica continuously (i.e., without any time gap), the creation of replica is started before the creation of Master is completed. So an error "requested entry does not exist" occurs. To avoid this export the environment variable CDS_DELAY_REPLICA_CREATE which will delay the creation of the replica. Usage of this environment variable:-Run the command "export CDS_DELAY_REPLICA_CREATE=sometimestamp". Here the timestamp should be between 0 to 5000 ms (milliseconds). Typically 2000 ms is used in most cases. The capability to restrict the assignment of endpoints to those in a user-specified set was added to RPC in OSF DCE 1.0.3. This allows DCE applications to operate in environments in which inter-network traffic is restricted to specified endpoints. The facility is activated by setting the RPC_RESTRICTED_PORTS environment variable with the list of end points to which dynamic assignment should be restricted before starting an RPC application. RPC_RESTRICTED_PORTS governs only the dynamic assignment of server and client ports by the RPC runtime. It does not affect well-known endpoints. The facility is turned on by setting the RPC_RESTRICTED_PORTS environment variable before starting an RPC application. The syntax of the variable is as follows:
For example:
To use RPC_RESTRICTED_PORTS for DCE itself, set the environment variable before starting your cell. The environment variable must be set whenever you restart DCE. Note that this facility does not add any security to RPC and is not intended as a security feature. It merely facilitates configuring a network "fire wall" to allow incoming calls to DCE servers. The OSF DCE Application Development Guide and the OSF DCE Application Development Reference may be misleading about what happens when an unauthenticated client calls a server that has specified authentication. In such a case, the RPC runtime will not perform any authentication, and the call will either reach the server manager code, or be rejected by the runtime, depending on the following conditions:
The bulk data transfer (for example, IN/OUT-pipes) over the connection-oriented (TCP/IP) RPC protocol is limited by the performance difference between the client and server machines. If the receiver process is significantly slower than the sender process (and cannot process data fast enough), the receiver process's virtual memory usage may grow rapidly until the remote procedure call fails with an rpc_s_no_memory status. The runtime looks for a RPC_SUPPORTED_NETADDRS environment variable, which allows a user or administrator to restrict the network addresses that a DCE server will advertise in the name space/endpoint-map. If this environment variable is set, only addresses in the list will be advertised in the name space or endpoint map. Addresses not found on the list will be excluded from the server's list of available addresses. The format of the RPC_SUPPORTED_NETADDRS string is as follows:
For example, assuming that host myhost is located at IP address 10.3.2.1, the Korn shell statements:
or
will force any servers started in the current shell to support only the addresses associated with the name myhost and the network address 10.3.2.1. Care must be used when calling exec() from a DCE application. HP DCE Threads sometimes sets open file descriptors to non-blocking mode, so that I/O calls block only the calling thread, not the entire process. This occurs unbeknownst to the application itself. HP provides wrappers for the exec() family of calls that, among other things, resets file descriptors to blocking mode if they were set non-blocking by HP DCE Threads and not the application. For file descriptors that were inherited across fork(), this also has the effect of resetting the file descriptor to blocking mode in the parent as well as the child. If the parent is a threaded program, it can cause the parent to hang due to a blocking I/O call. There are two possible work-arounds:
Note that if the exec() wrapper is circumvented, the new process may inherit file descriptors that are unexpectedly set non-blocking; some signals may be unexpectedly ignored or not ignored; and, if exec() is called without first calling fork(), the new process will probably be killed by SIGVTALRM as soon as it begins execution. Process forking from within RPC applications that use the connection-oriented (TCP/IP) RPC protocol is not supported. While it is generally safe for an application to perform a fork followed immediately by an exec(), the following sequence may not work for TCP/IP RPC programs:
Process forking from within RPC applications that use the connectionless protocol (UDP/IP) is supported, with the following restrictions:
The HP DCE Threads fcntl() wrapper does not provide for thread-synchronous file locking. The entire process will block when a call to fcntl() specifies F_SETLKW and the file is currently locked by another process. Note also that HP-UX file locks are a process-wide resource. For this reason, if multiple threads call fcntl() to lock the same section of a file, all the calls will succeed, and each thread will believe it holds the lock. However, only a single, process-wide lock is actually obtained — the first call obtains the lock, the second and subsequent calls have no effect. If one thread releases this lock, the other threads will continue to believe the file is locked, when in fact the process no longer holds any lock on that section of the file. Use mutex locks to ensure that only one thread at a time locks a particular file or section of a file. The previous comments regarding file locking with fcntl() also apply to lockf(). lockf() is not wrapped by DCE Threads.
The sec_login_valid_and_cert_ident() routine uses fcntl() for file locking, and should not be called by more than one thread at a time. If you must use sec_login_valid_and_cert_ident() in multiple threads, use a mutex to insure that only one thread at a time executes the call. No HP DCE programming interfaces call sec_login_valid_and_cert_ident() internally. Applications that need to obtain credentials in multiple threads will generally only need to call sec_login_validate_identity(), which is not affected by fcntl(). The HP DCE Threads semop() will not increment the semncnt or semzcnt kernel variables. Because the semop() wrapper adds the IPC_NOWAIT option before performing the semop() system call, the value of semncnt and semzcnt should not be trusted when using semop() to perform semaphore operations. Use of the signal() system call is not supported by HP DCE Threads, as it can interfere with signal handlers that are installed by Threads. In some cases, you can retain signal() calls in legacy code as follows:
The HP DCE Threads system() wrapper does not block SIGCHLD. It does set the handler for SIGQUIT and SIGINT to SIG_IGN, but only for the calling thread. This behavior differs from the behavior of the standard HP-UX version of system(). |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||