WO1998021654A1 - Log based data architecture for a transactional message queuing system - Google Patents

Log based data architecture for a transactional message queuing system Download PDF

Info

Publication number
WO1998021654A1
WO1998021654A1 PCT/US1997/020561 US9720561W WO9821654A1 WO 1998021654 A1 WO1998021654 A1 WO 1998021654A1 US 9720561 W US9720561 W US 9720561W WO 9821654 A1 WO9821654 A1 WO 9821654A1
Authority
WO
WIPO (PCT)
Prior art keywords
int
que
diag
file
msgh
Prior art date
Application number
PCT/US1997/020561
Other languages
French (fr)
Inventor
David W. H. Wong
Derek L. Schwenke
Original Assignee
Mitsubishi Electric Information Technology Center America, Inc.
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Mitsubishi Electric Information Technology Center America, Inc. filed Critical Mitsubishi Electric Information Technology Center America, Inc.
Priority to AU51771/98A priority Critical patent/AU5177198A/en
Priority to EP97946642A priority patent/EP1015973A4/en
Priority to JP52274998A priority patent/JP4280306B2/en
Publication of WO1998021654A1 publication Critical patent/WO1998021654A1/en

Links

Classifications

    • HELECTRICITY
    • H04ELECTRIC COMMUNICATION TECHNIQUE
    • H04LTRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
    • H04L69/00Network arrangements, protocols or services independent of the application payload and not provided for in the other groups of this subclass
    • H04L69/22Parsing or analysis of headers
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/07Responding to the occurrence of a fault, e.g. fault tolerance
    • G06F11/14Error detection or correction of the data by redundancy in operation
    • G06F11/1402Saving, restoring, recovering or retrying
    • G06F11/1471Saving, restoring, recovering or retrying involving logging of persistent data for recovery

Definitions

  • This invention relates to message queuing, and more particularly to a fast, reliable message queuing system for both client-server and mobile agent applications.
  • Message queuing is the most fundamental paradigm for communication between applications on different computer systems due to its inherent flexibility in allowing both synchronous and asynchronous processing.
  • the message queuing middleware infrastructure is a very flexible framework for a number of application domains in both general client-server as well as mobile agent computing arenas, to wit work flow computing, object messaging, transactional messaging and data replication services.
  • message queuing is used in general to be able to provide a failsafe storage for data records which are transmitted from one point to another. If, for instance, an error occurs and data is lost at one location, it can be reconstructed at a second location due to the storage inherent in message queuing.
  • queue file refers to the physical storage of messages that are in transmission. Queue files may also be viewed as holding cells for uncompleted operations. Basically, what this means is that if the receiver is not there to receive a given message, the message is held in the queue file and is deliverable at a later time. As a result, the queue files offer reliability in the retention of information that is transmitted.
  • the recovery data is not provided by the queue file itself.
  • queue files have not been utilized to identify the state of the file when an error or lost data has occurred, and have thus not been used to reconstruct the data file from data which is previously uncorrupted.
  • the recovery data is not provided by the queue file itself.
  • a message queuing infrastructure may support real-time on-line transaction processing using mobile agents.
  • the customer for instance, is a bank with geographically dispersed branches. Customer accounts are created and kept at the local branches where the account was opened. For illustrative purposes, this is called the home branch of the account . A copy of each account is also kept at the main office. A read operation on an account can be made from either the local branch or the main office. An update to an account, however, will require that both the home branch copy and the main office copy be updated in a coordinated fashion.
  • the local copy must then be updated.
  • This update can trigger an agent, which then automatically submits an enqueue request to the queue manager or queue server.
  • This queue manager in turn dequeues the request across a wide area network to another queue manager, which in turn, dequeues the update request to the database server for the mirror office accounts.
  • a message queue in this example provides asynchronous and reliable processing.
  • Asynchronous processing begins with the agent that is triggered by the database update at one location.
  • the agent submits the update request to the message queue manager in an asynchronous manner, and need not wait around for a response.
  • the message queue manager serves as holding cell for the request so that the requester can continue processing without the need to wait for a response.
  • the message queue manager also provides reliability in this example in that it maintains a copy of the update request in its queue until the recipient of this update request has acknowledged its receipt via a well-known handshaking protocol called the Two Phase Commit protocol, known in the industry as transactional message queuing.
  • a message queuing system that saves and stores messages and their state in an efficient single file on a single disk to enable rapid recovery from server failures.
  • the single disk, single file storage system into which messages and their states are stored eliminates writes to three different disks, the data disk, the index structure disk and the log disk.
  • the single disk, single file storage is made possible by clustering all information together in a contiguous space on the same disk. The result is that all writes are contained in one sweeping motion of the write head in which the write head moves only in one direction and only once to find the area where it needs to start writing messages and their states are stored.
  • a unique Queue Entry Map Table which includes control information, message blocks and log records in conjunction with single file disk storage that allows the write head never to have to back-up to traverse saved data when writing new records.
  • the system also permits locating damaged files without the requirement of scanning entire log files.
  • a control check point interval system is utilized to find the most recent uncorrupted data. Scanning to find the most recent check point interval permits rapid identification of the last queue. Subsequent scanning of log records after the checkpoint establishes the most up-to-date state of all messages. The above system permits data recovery in an order of magnitude less time than previous systems, while at the same time establishing an efficient forward writing mechanism to prevent the need for searching through unordered sectors .
  • a circular wrap around buffering system in which a modification of a previous sector is made by appending a new record at the last sector to indicate that the state of a file has changed, thus to reuse previous blocks that have been freed and no longer hold valid messages and/or log records .
  • the present invention thus provides a log-based data architecture for transactional message queuing systems which utilizes a combined on-disk file structure for the message queue data and log records. It is the combined queue data/log record file, in one embodiment, on a single disk, which improves write operation performance and reliability, while at the same time reducing the number of disks used.
  • system crash recovery is accelerated through the use of a Queue Entry Map Table which does not require searching though all of the log records to ascertain where the error occurred.
  • the use of the Queue Entry Map Table also permits a priori assigning the number of requirements on a queue data file that results in extensibility and flexibility to system administrators.
  • the subject system utilizes a circular queue that implies that there is potential wrap around of the queue data file for storage reuse. This requires that a reservation table or free space heap be maintained to ensure that when the queue wraps around, subsequent write operations do not overwrite queue data and/or log records that might still be valid.
  • the queue data storage architecture consists of a single flat file that is created when a queue manager is first initialized based on a fixed size for the queue.
  • the initial queue creation is based on the system administrator's feel for the peak load on the message queuing system, e.g., the maximum number of expected entries in message queue at any given point in time.
  • Each message in the queue data file contains a Message Header and a Message Body.
  • the Message Body which contains the message content, is stored on disk in subsequent contiguous blocks that follow the message header.
  • the queue data file is partitioned into a predefined number of logical segments or sectors which can be extended at run time.
  • Each segment contains a copy of the Queue Entry Map Table or QEMT for short, which is stored at the beginning of each segment.
  • the QEMT contains control information for the queue entries and log record information stored in the entire queue file. Message headers, message bodies, and log records are stored after the QEMT with potential mixing of message data and log record blocks .
  • the QEMT size depends on some expected maximum number of queue entries defined by the user at queue creation time. Since the log record takes up some deterministic number of bytes, the queue data file will consist of mixed data types of log records, message headers, message bodies, and QEMTs . When a new segment is reached in the queue data file, a new QEM Table is written to disk at the beginning of the new segment, with the message and log records following the QEM Table. Since the smallest on-disk data type is the log record, a segment in the queue data file is defined to consist of blocks, where one block is the size of the log record. This implementation enhancement simplifies development of search algorithms.
  • the state of a transactional message queuing system is captured by the control information contained in a QEMT.
  • the QEMT is defined as a static data structure that multiple threads can operate on, rather than each thread maintaining its own copy.
  • the subject invention provides a number of improvements over existing transactional message queuing data architectures . It improves on the performance of the write operation over existing message queuing architectures, which makes message queuing systems based on this invention highly appropriate for high throughput systems with low message residence times such as high speed banking applications.
  • the subject system is also applicable to the underlying reliable messaging infrastructure for the transport of agents over unreliable networks and/or networks with different bandwidths .
  • message data and log record write operations always proceed in the forward direction and both can be stored on the same disk file.
  • This system also improves the reliability of transactional message queuing systems.
  • this log-based data architecture there exists a single place where file corruption can occur versus two potential file corruption scenarios with separate queue data and log record files. Reliability is also improved since fewer disk files are used.
  • a combined queue data/log record file adheres to the Atomicity, Consistency, and Isolation properties of the well-known ACID properties.
  • the subject system allows the resulting message queuing system to support any method of message data access including First In First Out, Last In First Out or priority-based message data access, while at the same time reducing the amount of time needed for recovery from system crashes. Instead of scanning all data in an entire file for log records in traditional approaches, the subject system only requires that one test a few Queue ' Entry Map Tables first to determine the most recent checkpoint, and then proceed to scan the log records within that segment .
  • the subject system provides extensibility and flexibility to message queuing systems administration since the invention allows the administrator to control how much work they want to do on system recovery by a priori predefining the number of segments on a queue data file, and subsequently the number of checkpoint intervals, again determined a priori. System administrators can thus pay the overhead cost of writing the checkpoints up front to avoid paying the heavier cost of doing extensive log record scans upon recovery. This tradeoff can be adjusted and fine-tuned to suit the application requirements and domains .
  • the above advantages flow from the use of a pre-allocated on- disk queue buffer containing queue control information, message data, and transactional log records of message operations.
  • the on-disk queue buffer consists of a number of segments or sectors. Each segment consists of the same predefined number of blocks.
  • the Queue Entry Map Table contains control information data regarding the state of the individual queue entries, and pointer offsets to where on disk the messages are physically stored.
  • the Queue Entry Map Table serves as a fixed checkpoint interval for the entire message queuing system.
  • Messages and transactional log records of message operations are stored on the blocks in the segment such that message blocks and log record blocks can be intertwined. Moreover, there is no requirement that the log record for a particular message be stored contiguously to the message.
  • a message data write operation always proceeds in a forward manner for the disk head. Additionally, a message is stored contiguously on disk with no need for pointer traversal. Further, a log record write operation always proceeds in a forward manner for the disk head. Log records are written for change of state in a message operation that follows the Two Phase Commit protocol. Therefore, log records can be written for Prepare, Prepared, Commit, Abort, Acknowledge messages from a remote queue manager.
  • the entire queue can be scanned in a single pass.
  • on-disk garbage collection is always a linear process.
  • the read operation can follow the First In First Out, Last In First Out, or Priority-based policy such that no special provision is needed to implement any of the three policies.
  • the recovery procedure is accelerated by searching only the Queue Entry Map Tables timestamp. This is because, the most recent Queue Entry Map Table serves as the starting state for the recovery process. Log records following this table are then read sequentially and changes are then made to the in-memory copy of this most recent Queue Entry Map Table to reflect changes made after the last known checkpoint .
  • Figure 1 is a block diagram of a typical banking application utilizing the subject system in which messages flow from the main office to subsidiary branches;
  • Figure 2 is a diagrammatic representation of a two file system in which data is recorded at one file, whereas logs are recorded on a separate file, with the data stored at non- consecutive sectors and with the requirement that the entire log file be scanned in order to reconstruct an up-to-date state, the recovery process involving both the data file and log file to obtain the complete state of all messages in the system;
  • Figure 3 is a diagrammatic representation of the subject system in which a single file is utilized to store the data and QEMT mapping table to permit rapid recovery of lost data with a minimum amount of hardware and with reduced scanning time required for data recovery;
  • Figure 4 is a diagrammatic illustration of the storage of blocks of data within the file of Figure 3, indicating a circular file with a single write direction;
  • Figure 5 is a diagrammatic illustration of the possible QEMT control blocks at various well known positions or offsets within the file indicating that through the utilization of these QEMT control blocks, the position and/or location of valid data can be easily ascertained;
  • Figure 6 is a diagrammatic illustration showing the interdispersion of state change log records with the message data blocks to enable the forward writing of the file;
  • Figure 7 is a table illustrating the QEMT structure, including the QEMT sequence number which serves as a time stamp and which contains the incremental check point information required to restore the system;
  • Figure 8 is a table providing information to permit the restoration of individual message states
  • Figure 9 is a diagrammatic illustration of the forward directional flow of data in a wrap around system in which a circular queue is implemented
  • Figure 10 is a table illustrating the information stored in the incremental log record with the log entries of Figure 6 ;
  • Figure 11 is a flow chart illustrating the procedure for fetching a message from the queue
  • Figure 12 is a flow chart illustrating a procedure for writing a message in the queue.
  • Figure 13 is a flow chart illustrating the recovery process in which the most recent QEMT is identified by an initial scan, with subsequent reading of the log records following the identification of the most recent QEMT resulting in a completely restored state.
  • a message queuing system 10 is provided between branch offices of banks 12 and a main office 14 for the purpose of transmitting updated account information from the branches to the main office.
  • data is entered at terminals 16, 18 and 20 respectively at different branch offices of the bank.
  • This data is stored in local database servers 22, 24 and 26 of the respective branches, with each database server having its own local storage, here designated by reference character 28.
  • the output the database server is coupled to a series of message queuing servers 30, 32 and 34 respectively, each having their own storage units, here labeled by reference character 36.
  • the outputs of the message queuing servers are applied to a wide area network 40 which couples the outputs to a message queuing server 42 at the main office, with this server having associated respective storage units 44 as illustrated.
  • the message queuing servers 30, 32, and 34 communicate with a wide to a database server 50 having its associated units 52 as illustrated.
  • the output of the message queuing server 42 is coupled to a database server 50 having its associated units 52 as illustrated.
  • the information in this database is viewable at terminals 54 at the main office.
  • the message queuing system It is the purpose of the message queuing system to be able to reliably transmit updated account information from the branches so that it will reside at the main office. It is also important that the transaction at the branches can proceed without regard to direct connection to the central office.
  • message state information was stored on a log disk 80 which included records about each message stored in the data disk, including the order of arrival and its location on the data disk. Moreover, the state of the transaction was logged into log disk 80 for each of the messages and corresponding headers.
  • message data 60 and message header information 62 are stored on a single disk storage 90 in sequential sectors, here illustrated at 92, 94, 96 and 98. It is a feature of the subject invention that the message and header information is stored in an order which is accessible through the utilization of a queue entry management table, which locates message data through a checkpoint system to be described.
  • the queue entry management table contains sector information which includes entries for control information 100, message blocks 102 and log records 104 all of which are designed to uniquely specify the sector in which relevant data and headers can be found.
  • the QEMT therefore specifies the state of the system in so doing.
  • the Queue Entry Management Table is stored in file 90 interspersed between message data and header information.
  • file 90 is arranged such that contiguous sectors have blocks of information, here illustrated at 106, with the blocks of information entering from the left as illustrated by arrow 108 and traversing the file from left to right as illustrated by block number 1 entering from the left and block number 13 exiting from the right. It will be understood that the contiguous of blocks and the flow through the file creates a so-called write direction which does not change.
  • the purpose of interspersing the QEMT control blocks at regular intervals is to be able to quickly locate a complete system state containing specific message data and header information by merely specifying the checkpoint number or checkpoint interval, as the case may be.
  • the result is that it is possible to have message data and log record blocks to either side of a control QEMT control block, such that upon identification of a check point interval as being the last to have valid information, the contiguous blocks written after the QEMT block specifies where valid data may be found as well as its identity and location.
  • the QEMT control blocks provide the recovery process with well-known locations to examine the state of the system.
  • blocks 106 can be utilized as message data blocks as illustrated at 110 or incremental log blocks as illustrated at 112, with blocks 112 corresponding to log record 104 of Figure 3.
  • These log records record state changes to messages in contiguous downstream blocks.
  • the control block provides only some known point for the beginning of the examination of the file, whereas the log records provide information concerning individual messages in the file.
  • log record 104 is but one of a number of sequential log records relating to the data having its start point indicated by the QEMT control block. These log records record changes to information in the preceding message block so that a complete history of changes to that particular message block are annotated.
  • log record T x can describe a change in any one of the message blocks.
  • transactional log record T ⁇ can describe the state change for any message in the system, which could be an acknowledgment that the message has been received and is no longer needed to be kept, or that a message has been sent and has not been received or acknowledged, the above reflecting the two pass handshaking technique for the transmission of the secure messages in this type of system.
  • transactional log record T 1 could indicate that a new message has been added to the file at that particular point. It will be appreciated that the position of the log record is determined by the write head when the log record is created. Thus, when the log record is created at a time T x the write head is at a particular point in the file. However, the log record can refer to transactions and messages anywhere within the whole file structure .
  • transactional log records T 2 , T 3 and T 4 reflect that these messages have changed state, with these log records being posted sequentially in time.
  • the QEMT blocks and the log record blocks are insertable into the single file structure and since the single file structure in one embodiment has a information flow in one direction, it is possible to completely eliminate the two-file structure of the prior art. Moreover, the utilization of the QEMT blocks and the transactional log record blocks permits rapid diagnose of the effect of information interruption, with a way of specifying uniquely those messages which are uncorrupted, while thereafter permitting rapid recovery of the state of the system after failure.
  • the header includes the number of segments in a queue file 122, the segment size 124, the QEMT sequence number or timestamp 126, the sequence number of the last log record in the previous segment 128, the current segment number 130, the queue head pointer 132, the queue tail pointer 134, the next available block in the current segment 136, the list of QEMT entries 138, the reservation table of disk blocks 140, the pending transaction list acting as coordinator 142 and the pending transaction list acting as participant 144.
  • each QEMT entry 138 includes a sequence number 146, a message ID 148, a message operational mode 150, which is either Q put or Q get , the message recipient's node name 152, the message recipient's server name 154, the transaction state 156, which is either "active", “pending”, “abort” or “commit” , the participant 2 PC vote 158 which is the last known response that was received by the receiver, a set of additional flags 160 and a pointer on-disk location of message 162.
  • Queue Entry Management Table provides exact information as to the state of the file and more particularly any queue entry.
  • the transactional log record 112 of Figure 6 includes a special log record marker 162 in one embodiment.
  • a sequence number 164 is provided along with a message operational mode 166 which refers to either a Q get or Q put operation.
  • a message ID 168 is included in the transactional state 172 which includes "active", “pending”, “abort” or “commit” states, the participant 2 PC vote 174 mentioned above and a pointer 176 to on-disk location of message in queue file.
  • a block queue head pointer 182 effectively puts a lock on the head of the list so that no other user can access the head entry. Thereafter, the system increments the queue head pointer and sets the transaction state to "active read". This indicates the beginning of the handshaking process.
  • the system then unlocks the queue head pointer and then, as illustrated at 188, reads the messages from the on-disk queue file. Thereafter, the QEM Table is locked as illustrated at 190, whereafter the log record is written as illustrated at 192 and the QEM Table is unlocked as illustrated at 194.
  • the output of the unlock QEM Table step is referred to a decision block 196 which ascertains if the message transmission is transactional. If so, as illustrated at 198, the system runs a two-phase "commit" protocol to permit handshaking. This completes the Q put or write operation.
  • a Q get or read operation is described.
  • the queue tail pointer is locked as illustrated at 202 and a new QEM entry is created with the queue tail pointer being incremented as illustrated at 204.
  • the system fills in the QEM entry control information and sets the transaction state to "active control" .
  • the queue tail pointer is unlocked and the QEM table is locked as illustrated at 210.
  • the system allocates on-disk blocks from the reservation table, with a block crossing a segment boundary being indicated at decision block 214.
  • the system forces the QEMT check point write to disk. This refers to the fact of writing the in-memory copy to disk. It will be appreciated that block 206 updates the in-memory copy of the state of the QEM Table and thus the QEM entry. After having forced the QEMT check point write to disk as illustrated at 218, the system writes the message data to disk and unlocks the QEM Table. Decision block 220 establishes whether or not the messages is a transactional one and if so, runs a two phase commit protocol as illustrated at 221 to facilitate the handshaking. The end of the write sequence is illustrated at 222. It will be appreciated that block 220 refers to the receiver end running the handshaking protocol .
  • a recovery sequence is illustrated in which, upon starting as illustrated at 230, the queue table pointers are locked as illustrated at 232 and the system thereafter restores global data structure as illustrated at 234. This initializes the state of the system as a whole. Thereafter, as illustrated at 236 the system scans each QEMT in the queue file for the most recent QEMT. This establishes the most recent check point before communications interruption. Thereafter, as illustrated at 238, the system scans the log records in this segment for the log record with the latest QEMT. This means that the log records of the segment are applied to the messages referred to by the entries in the QEMT.
  • the system ascertains if there are more log records to scan. It will be appreciated that the QEMT specifies the most recent log record subsequent to the pointer associated with the QEMT in question. However, there may indeed be subsequent log records thereafter which need to be scanned. If this is the case, then the system contacts the participant about the transaction state of the message as illustrated at 242. In one instance, the receiver is queried as to whether it has received a message or not. Thereafter, the system invokes a two-phase "commit" protocol to resolve the transaction as illustrated at 244. This refers to the fact that the handshaking process is a two pass process. Thus, whatever state that one receives back from the receiver is used to restart the handshaking process at the point at which the system had failed.
  • the system updates the state of the reservation table and determines a new file pointer position.
  • the entire section is scanned to update the state of reservation table 140, with the determination of the new file pointer position being established by the current segment number 130 and the next available block in the current segment 136.
  • the system then writes out the new QEMT state to the disk at which point the recovery is complete as illustrated at 250.
  • Diag "Request Serviced by QS Thread No. %d” , arg->thr_no) ; switch (ENQ.msgh .mode)
  • Diag ( "DiskQ (%s) Queue Server in ABORT_MODE” , arg- >physical) ; else Diag ( "DiskQ (%s) Queue Server in COMMIT_MODE” , arg->physical) ; QS_QCommit (thr_str) ; break; case ADMI REQ_MODE :
  • Diag "DiskQ (%s) Queue Server in ADMINREQ_MODE” , arg- >physical ) ; QS_QAdmin(thr_str) ; if (shdn flag)
  • sprintf (quefile, "%s ⁇ %s.dat” , ath, physical) ; sprintf (qstate, "%s ⁇ %s . sta” , path, physical) ,-
  • hQHD CreateMutex (NULL, FALSE, QUE_HD_PTR_LOCK) ; if (IhQHD)
  • hQTL CreateMutex (NULL, FALSE, QUE_TL_PTR_LOCK) ; if (IhQTL)
  • hQEME CreateMutex (NULL, FALSE, QEME_TS_GEN_LOCK) ; if (! hQEME)
  • hLPG CreateMutex (NULL, FALSE, LPG_TS_GEN_LOCK) ; if (IhLPG)
  • hQEMT CreateMutex (NULL, FALSE, QEMT_LOCK) ; if (! hQEMT)
  • hMQstate CreateMutex (NULL, FALSE, MQstate_LOCK) ; if (! hMQstate)
  • hMQops CreateMutex (NULL, FALSE, MQops_LOCK) ; if (! hMQops)
  • hQSHDN CreateMutex (NULL, FALSE, QSHDN_LOCK) ; if (! hQSHDN)
  • hQSHDN_Event CreateEven (NULL, RUE, FALSE, QSHDN_EVENT) if ( ! hQSHDN_Event )
  • Que__File_Handle Create_Queue_File (quefile, qstate, max elms,num segs) ;
  • MAX_ELMS max_elms
  • NUM SEGS num segs
  • Return__Status CloseHandle (Que_File_Handle) ;
  • Last_Pending_Get (LPG_TS_STR *) malloc (sizeof (LPG_TS_STR) ) ;
  • Active_LREC_L ⁇ st (LRCLST *) malloc (sizeof (LRCLST) ) ;
  • Active_LREC_List->max_txns_per_seg max_txns_per_seg;
  • Que_State_Handle Open_Queue_File (qstate) ;
  • temp_time time (&MQstate->first_start_time)
  • temp_time time (&MQstate->last_restart_time) ;
  • temp_time time (&MQstate->last_restart_time) ;
  • hQHD OpenMutex (SYNCHRONIZE, FALSE, QUE_HD_PTR_LOCK) ; if (IhQHD)
  • hQTL OpenMutex (SYNCHRONIZE, FALSE, QUE_TL_PTR_LOCK) ; if (IhQTL)
  • hQEMT OpenMutex (SYNCHRONIZE, FALSE, QEMT_LOCK) ; if (! hQEMT)
  • Return_Status CloseHandle (QueJFileJHandle) ;
  • Que_State_Handle OpenJQueueJFile (qstate)
  • dwPointer SetFilePointer (Que_State_Handle ,
  • DiagC'status FALSE"
  • hQHD OpenMutex (SYNCHRONIZE, FALSE, QUE_HD_PTR_LOCK) ; if (IhQHD)
  • hQTL OpenMutex (SYNCHRONIZE, FALSE, QUE_TL_PTRJLOCK) ; if (IhQTL)
  • hQEMT OpenMutex (SYNCHRONIZE, FALSE, QUEJTLJPTR_LOCK) ,- if (! QEMT)
  • Return_Status Find__MTlist (PendingJTXNs, &This_TXN, log_rec .mid) ; switch (log rec . txn_.state)
  • Add_MTlist (&PendingJTXNs , &This_TXN, log_rec.mid) ; Add Tlist(&This TXN->ops,log rec.qeme no);
  • QRJResolveJTXNJO (ThisJTXN_ops->qeme_no, COMMIT) ; else QR_Resolve_TXNjOp(This_TXN_ops->qeme_no, ABORT) ;
  • This TXN ops This TXN ops->next;
  • ThisJTXN ThisJTXN- >next
  • ⁇ *msg_block NIL; msg block++;
  • ⁇ status Cycle_QEME (qeme__no, &lpqeme) ,- if (!Add RST Entry (lpqeme- >offse . segmen , lpqeme- >offset . block) )
  • Que_File_Handle thr_arg->Que_File_Handle ;
  • hQEMT OpenMutex (SYNCHRONIZE, FALSE, QEMT_LOCK) ; if (!hQEMT)
  • ⁇ hMQops OpenMutex (SYNCHRONIZE, FALSE, MQops_LOCK) ; if (! hMQops)
  • hQEMT OpenMute (SYNCHRONIZE, FALSE, QEMTJLOCK) , if (! hQEMT)
  • hQSHDN OpenMute (SYNCHRONIZE, FALSE, QSHDN_LOCK) , if (! hQSHDN)
  • hMQops OpenMutex (SYNCHRONIZE, FALSE, MQops_LOCK) ; if (! hMQops)
  • Retum_Status WriteFile (Que_StateJHandle ,
  • Return_Status CloseHandle (Que_State_Handle) ;
  • hQTL OpenMutex (SYNCHRONIZE, FALSE, QUE_TL_PTR_LOCK) , if ('hQTL)
  • hQEMT OpenMutex (SYNCHRONIZE, FALSE, QEMT_LOCK) , if ('hQEMT)
  • hQSHDN OpenMutex (SYNCHRONIZE, FALSE, QSHDN_LOCK) , if ('hQSHDN)
  • Diag "QS_Admin: Option %d Not Valid” , thr_arg- >lpsmbuf- >msgh . sub_mode)
  • Diag "DiskQ (%s) : Termination for TID: %d from Host: %x" , thr_arg->qname, thr_arg->lpsmbuf- >msgh . mid .tid, thr_arg- >lpsmbuf->msgh .mid.host) ; /*
  • Diag C'MID . tid %d" , thr_arg- >lpsmbuf - >msgh . mid . tid) ;
  • This_TXN_ops This_TXN_ops->next; count++; // increment txn ops counter ⁇
  • log_rec.mode mode
  • log_rec . flags lpsmbuf->msgh. flags
  • log_rec . qeme_no NIL
  • log_rec. txn_state mode
  • log_rec.vote mode
  • log_rec.mid.host lpsmbuf->msgh.mid. host
  • log_rec .mid. tid lpsmbuf->msgh. mid. tid
  • log_rec.mid.uid lpsmbuf->msgh. mid.uid
  • log_rec.offset . segment NIL
  • log_rec .offse .block NIL;
  • Queue element size // - disk block size is the larger of // - log record or half a msg header #define QUE_FILE_SIZE 50 #define QUE_EXTENT 0.0 // queue file extent percentage #define BLOCK 46 // size of a block on disk ttdefine MSG_HDR_BLOCKS 2 // number of blocks for msg header #define MSG_BODY_BLOCKS 177 // ceil ( (8192-sizeof (MSGH) ) /BLOCK) // blocks for msg body
  • IpPTLIST ptl_ptr // pointer to list of pending txns ⁇ QEMT, *lpQEMT; typedef struct opstats // RT operational statistics mt pending_gets ,- // pending gets only int pending_puts ,- // pending puts only int num_gets; // committed gets only int num_puts ; // committed puts only int num_aborts; int num_commits ;
  • HANDLE Que File Handle // queue datafile handle lpQHANDLE qhandle; // handle to SHM buffers IpSMBUF lpsmbuf; // pointer to SMBUF ⁇ TSTR, *lpTSTR; typedef struct mstr ⁇ // Structure for passing thread data
  • BOOL Delete_Queue_File ( CHAR *FileName) ,- int Find_Num_Entries ( lpCNTSTR *cnt_ptr) ; int Find_QEME ( lpMID mid, int *qeme_no2, lpQEME *lpqeme2) ; int CycleJQ ⁇ ME( int qeme_no, lpQEME *lpqeme2) ;
  • BOOL Check_Queue_Empty ( lpQEMT lpqemt) ; void Update_Globals () ; void Conv_from_MTlist () ; void Conv toJMTlist () ; void Add_Tlis ( lpTLIST *head, int qeme_no) ,- void Add_MTlist ( lpMTLIST *head, lpMTLIST *tail, MID mid) ,-
  • BOOL Find_MTlis ( lpMTLIST head, lpMTLIST *pres, MID mid) ;
  • BOOL FindJTlist ( lpTLIST head, int qeme_no) ,- void Del_MTlist_All ( lpMTLIST *head) ,-
  • BOOL Del_MTlist ( lpMTLIST *head, MID mid) ; void DelJTlist ( lpTLIST *head) ; void Sub_Addr ( LONG *diff, BLAD *x, BLAD *y) ; void Conv_Addr ( LONG *diff, BLAD *x) ; int Gen_QEM_Seq_No ( IpSN tSeq_No) ; int Gen_LREC_Seq_No ( IpSN tSeq_No) ;
  • IpSMBUF lpsmbuf IpSMBUF lpsmbuf
  • void print_MSGH lpMSGH lpmsgh
  • void print_MSGB
  • hQHD OpenMutex (SYNCHRONIZE, FALSE, QUE_HD_PTR_LOCK) ,- if OhQHD)
  • MQEMT- >quejhd_ptr NIL
  • MQEMT- >que tl ptr NIL
  • host thr_arg->lpsmbuf ->msgh. mid. host , • lpqeme->mid.
  • tid thr_arg->lpsmbuf ->msgh.mid .
  • Diag("QS_QGe : Can't OpenMutex for MQops stats lock”); if ((status WaitForSingleObject (hMQops, QUEJLOCKJTIMEOUT) )
  • log_rec .mid.uid thr_arg->lpsmbuf->msgh.mid.uid
  • log_rec . offset . segment lpqeme- >offset . segment ;
  • log_rec .offset .block lpqeme->offset .block ,-
  • Add_MTlist (&Pending_TXNs, &This_TXN, lpqeme- >mid) ,- AddJTlist ( &ThisJTXN- >ops , qeme_no) ,-
  • Last Pending Get->timestamp lpqeme->timestamp
  • lpsmbuf thr_arg- >lpsmbuf ;
  • Que_File_Handle thr_arg- >Que_File_Handle ;
  • hQHD OpenMutex (SYNCHRONIZE, FALSE, QUE_HD_PTR_LOCK) ; if (IhQHD)
  • Diag("DiskQ(%s) is FULL” , thr_arg->qname) ; if (thr_arg->qhandle ! QUEUE_TEST_VALUE)
  • hQEMT OpenMutex (SYNCHRONIZE, FALSE, QEMT_LOCK) ; if (! hQEMT)
  • ⁇ hMQops OpenMutex ( SYNCHRONIZE , FALSE , MQops_LOCK) ; if ( ! hMQops )
  • Diag( "DiskQ(% ⁇ ) is too fragmented - PUT failed. ", thr_arg->qname) ,- if (thr_arg->qhandle ! QUEUE_TEST_VALUE)
  • hQEME OpenMute (SYNCHRONIZE, FALSE, QEMEJTSJGENJLOCK) ; if (! hQEME)

Abstract

A message queuing system is provided that saves and stores messages and their state in an efficient single file on a single disk to enable rapid recovery from server failures. The single disk, single file storage system into which messages and their states are stored eliminates writes to three different disks, the data disk, the index structure disk and the log disk. The single disk, single file storage is made possible by clustering all information together in a contiguous space on the same disk. The result is that all writes are contained in one sweeping motion of the write head in which the write head moves only in one direction and only once to find the area where it needs to start writing messages and their states are stored. In order to keep track of the clustered information, a unique Queue Entry Map Table (100) is used which includes control information (100), message blocks (102) and log records (104) in conjunction with single file disk storage that allows the write head never to have to back-up to traverse saved data when writing new records. The system also permits locating damaged files without the requirement of scanning entire log files.

Description

LOG BASED DATA ARCHITECTURE FOR A TRANSACTIONAL MESSAGE
QUEUING SYSTEM.
FIELD OF INVENTION
This invention relates to message queuing, and more particularly to a fast, reliable message queuing system for both client-server and mobile agent applications.
CROSS-REFERENCE TO RELATED APPLICATIONS
A claim of priority is made to U.S. Provisional Patent Application Serial No. 60/030,905, filed November 14, 1996, entitled LOG BASED DATA ARCHITECTURE FOR A TRANSACTIONAL MESSAGE QUEUING SYSTEM.
BACKGROUND OF THE INVENTION
Message queuing is the most fundamental paradigm for communication between applications on different computer systems due to its inherent flexibility in allowing both synchronous and asynchronous processing. The message queuing middleware infrastructure is a very flexible framework for a number of application domains in both general client-server as well as mobile agent computing arenas, to wit work flow computing, object messaging, transactional messaging and data replication services.
It will be appreciated that in many transactional messaging scenarios data is oftentimes lost during the transmission. This is no more catastrophic than in the banking industry in which banking records transmitted from one location to another can be lost due to server failures, transmission line failures or other artifacts. It is incumbent upon the system managers to be able to quickly locate the fact that an error has occurred and to be able to reconstruct the data from a known point where the data was valid.
Establishing that point at which an error has occurred has in the past been accomplished by systems which scan an entire so- called log file to reconstruct the up-to-date state of the system before the crash. Log files are routinely utilized with their associated time stamps to identify messages and the data they contain. However, the scanning of entire log files to ascertain the up-to-date state can require scanning as many as 1,000 log records .
Not only is the scanning of the overall log record an inefficient way to ascertain where an error occurred and to be able to reconstruct files from that point, systems in the past have required two disk files, one serving as a data file, and the other serving as a log file.
Moreover, the correlation between the log entries and the data files or sectors is complicated by the fact that in the past, sectors were stored in some indiscriminant order, leaving the mapping between the log file and the sectors a somewhat time consuming process .
By way of further background, it will be appreciated that message queuing is used in general to be able to provide a failsafe storage for data records which are transmitted from one point to another. If, for instance, an error occurs and data is lost at one location, it can be reconstructed at a second location due to the storage inherent in message queuing.
As an example, it is desirable, especially in stock market trades, that any interruption in trading to be minimized to minutes as opposed to hours. On occasion, however, when system servers go down, recovery can take from two to eight hours depending on the number of trades in the system at that time. There is thus a need to minimize down time and expense of locating and reconstructing damaged files .
Note that as used herein, the term queue file refers to the physical storage of messages that are in transmission. Queue files may also be viewed as holding cells for uncompleted operations. Basically, what this means is that if the receiver is not there to receive a given message, the message is held in the queue file and is deliverable at a later time. As a result, the queue files offer reliability in the retention of information that is transmitted.
Moreover, in traditional systems, the recovery data is not provided by the queue file itself. Thus, queue files have not been utilized to identify the state of the file when an error or lost data has occurred, and have thus not been used to reconstruct the data file from data which is previously uncorrupted. In a traditional system, the recovery data is not provided by the queue file itself.
Another example of how message queuing is applied to a real- world application involves how a message queuing infrastructure may support real-time on-line transaction processing using mobile agents. In this example, the customer, for instance, is a bank with geographically dispersed branches. Customer accounts are created and kept at the local branches where the account was opened. For illustrative purposes, this is called the home branch of the account . A copy of each account is also kept at the main office. A read operation on an account can be made from either the local branch or the main office. An update to an account, however, will require that both the home branch copy and the main office copy be updated in a coordinated fashion.
If the update request occurred at the home branch, the local copy must then be updated. This update can trigger an agent, which then automatically submits an enqueue request to the queue manager or queue server. This queue manager in turn dequeues the request across a wide area network to another queue manager, which in turn, dequeues the update request to the database server for the mirror office accounts.
A message queue in this example provides asynchronous and reliable processing. Asynchronous processing begins with the agent that is triggered by the database update at one location. The agent submits the update request to the message queue manager in an asynchronous manner, and need not wait around for a response. The message queue manager serves as holding cell for the request so that the requester can continue processing without the need to wait for a response. The message queue manager also provides reliability in this example in that it maintains a copy of the update request in its queue until the recipient of this update request has acknowledged its receipt via a well-known handshaking protocol called the Two Phase Commit protocol, known in the industry as transactional message queuing.
While these types of message queuing systems have operated reliably in the past, they have relied on a data architecture that uses separate queue data and log record files to store the messages that are appended to a message queue. This architecture prevents rapid repair at the time of a serve crash and requires two storage disks, one for data and one for the log records. Moreover, traditional message queuing architectures are generally not optimized for write operations without requiring extra hardware to work efficiently, and are not appropriate for high throughput systems with low message residence times . The separate queue data and log files mentioned above also introduce an extra level of unreliability since there exists two points of potential file corruption and media failure. Additionally, there is usually no means for the message queuing systems administrator to predefine the amount of work needed to do recovery a priori .
Note, the above systems are commercially available as Digital Equipment Corporation's DECmessageQ, IBM's MQ Series, and Transarc ' s Encina RQS .
SUMMARY OF INVENTION
In order to solve the above noted problems with traditional message queuing, a message queuing system is provided that saves and stores messages and their state in an efficient single file on a single disk to enable rapid recovery from server failures. The single disk, single file storage system into which messages and their states are stored eliminates writes to three different disks, the data disk, the index structure disk and the log disk. The single disk, single file storage is made possible by clustering all information together in a contiguous space on the same disk. The result is that all writes are contained in one sweeping motion of the write head in which the write head moves only in one direction and only once to find the area where it needs to start writing messages and their states are stored. In order to keep track of the clustered information, a unique Queue Entry Map Table is used which includes control information, message blocks and log records in conjunction with single file disk storage that allows the write head never to have to back-up to traverse saved data when writing new records. The system also permits locating damaged files without the requirement of scanning entire log files.
In order to find the most recent valid data, a control check point interval system is utilized to find the most recent uncorrupted data. Scanning to find the most recent check point interval permits rapid identification of the last queue. Subsequent scanning of log records after the checkpoint establishes the most up-to-date state of all messages. The above system permits data recovery in an order of magnitude less time than previous systems, while at the same time establishing an efficient forward writing mechanism to prevent the need for searching through unordered sectors .
In one embodiment, a circular wrap around buffering system is used in which a modification of a previous sector is made by appending a new record at the last sector to indicate that the state of a file has changed, thus to reuse previous blocks that have been freed and no longer hold valid messages and/or log records .
The present invention thus provides a log-based data architecture for transactional message queuing systems which utilizes a combined on-disk file structure for the message queue data and log records. It is the combined queue data/log record file, in one embodiment, on a single disk, which improves write operation performance and reliability, while at the same time reducing the number of disks used. As mentioned above, system crash recovery is accelerated through the use of a Queue Entry Map Table which does not require searching though all of the log records to ascertain where the error occurred. The use of the Queue Entry Map Table also permits a priori assigning the number of requirements on a queue data file that results in extensibility and flexibility to system administrators.
Also as mentioned above, the subject system utilizes a circular queue that implies that there is potential wrap around of the queue data file for storage reuse. This requires that a reservation table or free space heap be maintained to ensure that when the queue wraps around, subsequent write operations do not overwrite queue data and/or log records that might still be valid.
In one embodiment, the queue data storage architecture consists of a single flat file that is created when a queue manager is first initialized based on a fixed size for the queue. The initial queue creation is based on the system administrator's feel for the peak load on the message queuing system, e.g., the maximum number of expected entries in message queue at any given point in time. Each message in the queue data file contains a Message Header and a Message Body. The Message Body, which contains the message content, is stored on disk in subsequent contiguous blocks that follow the message header.
In the above embodiment, the queue data file is partitioned into a predefined number of logical segments or sectors which can be extended at run time. Each segment contains a copy of the Queue Entry Map Table or QEMT for short, which is stored at the beginning of each segment. The QEMT contains control information for the queue entries and log record information stored in the entire queue file. Message headers, message bodies, and log records are stored after the QEMT with potential mixing of message data and log record blocks .
As will be appreciated, the QEMT size depends on some expected maximum number of queue entries defined by the user at queue creation time. Since the log record takes up some deterministic number of bytes, the queue data file will consist of mixed data types of log records, message headers, message bodies, and QEMTs . When a new segment is reached in the queue data file, a new QEM Table is written to disk at the beginning of the new segment, with the message and log records following the QEM Table. Since the smallest on-disk data type is the log record, a segment in the queue data file is defined to consist of blocks, where one block is the size of the log record. This implementation enhancement simplifies development of search algorithms.
The state of a transactional message queuing system is captured by the control information contained in a QEMT. The QEMT is defined as a static data structure that multiple threads can operate on, rather than each thread maintaining its own copy.
As a result of the log-based data architecture, the subject invention provides a number of improvements over existing transactional message queuing data architectures . It improves on the performance of the write operation over existing message queuing architectures, which makes message queuing systems based on this invention highly appropriate for high throughput systems with low message residence times such as high speed banking applications. The subject system is also applicable to the underlying reliable messaging infrastructure for the transport of agents over unreliable networks and/or networks with different bandwidths .
Moreover, message data and log record write operations always proceed in the forward direction and both can be stored on the same disk file.
This system also improves the reliability of transactional message queuing systems. In this log-based data architecture, there exists a single place where file corruption can occur versus two potential file corruption scenarios with separate queue data and log record files. Reliability is also improved since fewer disk files are used. A combined queue data/log record file adheres to the Atomicity, Consistency, and Isolation properties of the well-known ACID properties. Also, as will be seen, one can utilize existing RAID technology to do transparent duplicate writes. The subject system allows the resulting message queuing system to support any method of message data access including First In First Out, Last In First Out or priority-based message data access, while at the same time reducing the amount of time needed for recovery from system crashes. Instead of scanning all data in an entire file for log records in traditional approaches, the subject system only requires that one test a few Queue' Entry Map Tables first to determine the most recent checkpoint, and then proceed to scan the log records within that segment .
Moreover, the subject system provides extensibility and flexibility to message queuing systems administration since the invention allows the administrator to control how much work they want to do on system recovery by a priori predefining the number of segments on a queue data file, and subsequently the number of checkpoint intervals, again determined a priori. System administrators can thus pay the overhead cost of writing the checkpoints up front to avoid paying the heavier cost of doing extensive log record scans upon recovery. This tradeoff can be adjusted and fine-tuned to suit the application requirements and domains .
The above advantages flow from the use of a pre-allocated on- disk queue buffer containing queue control information, message data, and transactional log records of message operations. The on-disk queue buffer consists of a number of segments or sectors. Each segment consists of the same predefined number of blocks. At the beginning of each segment is the aforementioned Queue Entry Map Table, which contains control information data regarding the state of the individual queue entries, and pointer offsets to where on disk the messages are physically stored. The Queue Entry Map Table serves as a fixed checkpoint interval for the entire message queuing system. Messages and transactional log records of message operations are stored on the blocks in the segment such that message blocks and log record blocks can be intertwined. Moreover, there is no requirement that the log record for a particular message be stored contiguously to the message.
As a feature of the subject invention, a message data write operation always proceeds in a forward manner for the disk head. Additionally, a message is stored contiguously on disk with no need for pointer traversal. Further, a log record write operation always proceeds in a forward manner for the disk head. Log records are written for change of state in a message operation that follows the Two Phase Commit protocol. Therefore, log records can be written for Prepare, Prepared, Commit, Abort, Acknowledge messages from a remote queue manager.
As an another unique feature, the entire queue can be scanned in a single pass. Moreover, on-disk garbage collection is always a linear process. Additionally, there exists a number of Queue Entry Map Tables on the same file, with the unique sequence number of the most recent table being stored on disk on a graceful shutdown of the queue manager.
Importantly, the read operation can follow the First In First Out, Last In First Out, or Priority-based policy such that no special provision is needed to implement any of the three policies.
Moreover, the recovery procedure is accelerated by searching only the Queue Entry Map Tables timestamp. This is because, the most recent Queue Entry Map Table serves as the starting state for the recovery process. Log records following this table are then read sequentially and changes are then made to the in-memory copy of this most recent Queue Entry Map Table to reflect changes made after the last known checkpoint .
BRIEF DESCRIPTION OF THE DRAWINGS
These and other features of the Subject Invention will be better understood with reference to the Detailed Description taken in conjunction with the Drawings, of which: Figure 1 is a block diagram of a typical banking application utilizing the subject system in which messages flow from the main office to subsidiary branches;
Figure 2 is a diagrammatic representation of a two file system in which data is recorded at one file, whereas logs are recorded on a separate file, with the data stored at non- consecutive sectors and with the requirement that the entire log file be scanned in order to reconstruct an up-to-date state, the recovery process involving both the data file and log file to obtain the complete state of all messages in the system;
Figure 3 is a diagrammatic representation of the subject system in which a single file is utilized to store the data and QEMT mapping table to permit rapid recovery of lost data with a minimum amount of hardware and with reduced scanning time required for data recovery;
Figure 4 is a diagrammatic illustration of the storage of blocks of data within the file of Figure 3, indicating a circular file with a single write direction;
Figure 5 is a diagrammatic illustration of the possible QEMT control blocks at various well known positions or offsets within the file indicating that through the utilization of these QEMT control blocks, the position and/or location of valid data can be easily ascertained;
Figure 6 is a diagrammatic illustration showing the interdispersion of state change log records with the message data blocks to enable the forward writing of the file;
Figure 7 is a table illustrating the QEMT structure, including the QEMT sequence number which serves as a time stamp and which contains the incremental check point information required to restore the system;
Figure 8 is a table providing information to permit the restoration of individual message states; Figure 9 is a diagrammatic illustration of the forward directional flow of data in a wrap around system in which a circular queue is implemented;
Figure 10 is a table illustrating the information stored in the incremental log record with the log entries of Figure 6 ;
Figure 11 is a flow chart illustrating the procedure for fetching a message from the queue;
Figure 12 is a flow chart illustrating a procedure for writing a message in the queue; and,
Figure 13 is a flow chart illustrating the recovery process in which the most recent QEMT is identified by an initial scan, with subsequent reading of the log records following the identification of the most recent QEMT resulting in a completely restored state.
DETAILED DESCRIPTION
Referring now to Figure 1, a message queuing system 10 is provided between branch offices of banks 12 and a main office 14 for the purpose of transmitting updated account information from the branches to the main office. In order to accomplish this, data is entered at terminals 16, 18 and 20 respectively at different branch offices of the bank. This data is stored in local database servers 22, 24 and 26 of the respective branches, with each database server having its own local storage, here designated by reference character 28.
The output the database server is coupled to a series of message queuing servers 30, 32 and 34 respectively, each having their own storage units, here labeled by reference character 36.
The outputs of the message queuing servers are applied to a wide area network 40 which couples the outputs to a message queuing server 42 at the main office, with this server having associated respective storage units 44 as illustrated. The message queuing servers 30, 32, and 34 communicate with a wide to a database server 50 having its associated units 52 as illustrated. The output of the message queuing server 42 is coupled to a database server 50 having its associated units 52 as illustrated. The information in this database is viewable at terminals 54 at the main office.
It is the purpose of the message queuing system to be able to reliably transmit updated account information from the branches so that it will reside at the main office. It is also important that the transaction at the branches can proceed without regard to direct connection to the central office.
Referring now to Figure 2, in the past messages and headers such as illustrated at 60 and 62 were stored on data disks 64 in sectors 66, 68, 70 and 72, with the message and accompanying header being randomly placed within the sectors .
At the same time, message state information was stored on a log disk 80 which included records about each message stored in the data disk, including the order of arrival and its location on the data disk. Moreover, the state of the transaction was logged into log disk 80 for each of the messages and corresponding headers.
In the case of an interrupted transmission as indicated by "X" 82, in the past was a requirement that the entire log file, here illustrated at 84, be scanned to be able to reconstruct the up-to-date state of the data disk file just prior to the interruption of the transmission. As mentioned hereinbefore, this is a time-consuming process in which the entire log file must be scanned in order to be able to reconstruct the state of the system just prior to the crash. The situation is made even more complicated due to the storage of the message and header information at nonsequential sectors on the data disk, requiring the interaction of the log file and the data file in order to locate those messages which are uncorrupted at the time of the interruption of the transmission.
Referring now to Figure 3, in the subject system message data 60 and message header information 62 are stored on a single disk storage 90 in sequential sectors, here illustrated at 92, 94, 96 and 98. It is a feature of the subject invention that the message and header information is stored in an order which is accessible through the utilization of a queue entry management table, which locates message data through a checkpoint system to be described.
It will be appreciated that the message data is not stored across all of the sectors, but rather is stored in the above- mentioned sequential manner.
In order to be able to access the data stored in file 90, the queue entry management table, or QEMT, contains sector information which includes entries for control information 100, message blocks 102 and log records 104 all of which are designed to uniquely specify the sector in which relevant data and headers can be found. The QEMT therefore specifies the state of the system in so doing.
As will be seen in connection with Figures 4, 5 and 6 the Queue Entry Management Table is stored in file 90 interspersed between message data and header information.
Referring now to Figure 4, in one embodiment, file 90 is arranged such that contiguous sectors have blocks of information, here illustrated at 106, with the blocks of information entering from the left as illustrated by arrow 108 and traversing the file from left to right as illustrated by block number 1 entering from the left and block number 13 exiting from the right. It will be understood that the contiguous of blocks and the flow through the file creates a so-called write direction which does not change.
Referring now to Figure 5, it will be seen that the aforementioned QEMT control blocks 100 can be interspersed between other contiguous blocks 106 so that the position of the QEMT control information blocks 100 specify check points at well-known offsets throughout file 90.
The purpose of interspersing the QEMT control blocks at regular intervals is to be able to quickly locate a complete system state containing specific message data and header information by merely specifying the checkpoint number or checkpoint interval, as the case may be. The result is that it is possible to have message data and log record blocks to either side of a control QEMT control block, such that upon identification of a check point interval as being the last to have valid information, the contiguous blocks written after the QEMT block specifies where valid data may be found as well as its identity and location.
As an alternative explanation, the QEMT control blocks provide the recovery process with well-known locations to examine the state of the system.
Referring now to Figure 6, it will be seen that blocks 106 can be utilized as message data blocks as illustrated at 110 or incremental log blocks as illustrated at 112, with blocks 112 corresponding to log record 104 of Figure 3. These log records record state changes to messages in contiguous downstream blocks. Note, the control block provides only some known point for the beginning of the examination of the file, whereas the log records provide information concerning individual messages in the file.
Referring back to Figure 3, it will be appreciated that log record 104 is but one of a number of sequential log records relating to the data having its start point indicated by the QEMT control block. These log records record changes to information in the preceding message block so that a complete history of changes to that particular message block are annotated.
Referring back to Figure 6, it is noted that a given number of message blocks are bounded by QEMT control blocks which specify additional message data blocks that have occurred after the check point. Within this sector are transactional log records 112. It will be seen that log record Tx can describe a change in any one of the message blocks. As can be seen from arrow 114, the information flow is from left to right. This being the case, transactional log record Tλ can describe the state change for any message in the system, which could be an acknowledgment that the message has been received and is no longer needed to be kept, or that a message has been sent and has not been received or acknowledged, the above reflecting the two pass handshaking technique for the transmission of the secure messages in this type of system. For instance, transactional log record T1 could indicate that a new message has been added to the file at that particular point. It will be appreciated that the position of the log record is determined by the write head when the log record is created. Thus, when the log record is created at a time Tx the write head is at a particular point in the file. However, the log record can refer to transactions and messages anywhere within the whole file structure .
Likewise, transactional log records T2, T3 and T4 reflect that these messages have changed state, with these log records being posted sequentially in time.
It will be appreciated that since the QEMT blocks and the log record blocks are insertable into the single file structure and since the single file structure in one embodiment has a information flow in one direction, it is possible to completely eliminate the two-file structure of the prior art. Moreover, the utilization of the QEMT blocks and the transactional log record blocks permits rapid diagnose of the effect of information interruption, with a way of specifying uniquely those messages which are uncorrupted, while thereafter permitting rapid recovery of the state of the system after failure.
Referring now to Figure 7, the organization of the Queue Entry Management Table header is illustrated at 120. As can be seen, in one embodiment, the header includes the number of segments in a queue file 122, the segment size 124, the QEMT sequence number or timestamp 126, the sequence number of the last log record in the previous segment 128, the current segment number 130, the queue head pointer 132, the queue tail pointer 134, the next available block in the current segment 136, the list of QEMT entries 138, the reservation table of disk blocks 140, the pending transaction list acting as coordinator 142 and the pending transaction list acting as participant 144.
It will be appreciated that the information contained in the header is supporting information for the recovery process. Referring now to Figure 8, each QEMT entry 138 includes a sequence number 146, a message ID 148, a message operational mode 150, which is either Qput or Qget, the message recipient's node name 152, the message recipient's server name 154, the transaction state 156, which is either "active", "pending", "abort" or "commit" , the participant 2 PC vote 158 which is the last known response that was received by the receiver, a set of additional flags 160 and a pointer on-disk location of message 162.
Thus the Queue Entry Management Table provides exact information as to the state of the file and more particularly any queue entry.
Referring now to Figure 9, what will be appreciated is that since a single message is stored in contiguous blocks, the reprocess involves reading contiguous blocks back. As a result, this cuts down on the head movement during a read operation.
In summary, in the prior art doing a read might require the read head to traverse noncontiguous blocks, and therefore take a considerable amount of time. In the subject system since the message are stored in contiguous blocks, only traversing these contiguous blocks is necessary in the read operation. Likewise, for a sequential write operation, the head traverses only a limited -amount of the file.
In short, because there is a forward directional flow and wrap around on subsequent writes, the data is arranged in contiguous blocks and the above advantages flow therefrom.
Referring now to Figure 10, the transactional log record 112 of Figure 6 includes a special log record marker 162 in one embodiment. In this embodiment, a sequence number 164 is provided along with a message operational mode 166 which refers to either a Qget or Qput operation. Also included is a message ID 168, a set of operational flags 170, the transactional state 172 which includes "active", "pending", "abort" or "commit" states, the participant 2 PC vote 174 mentioned above and a pointer 176 to on-disk location of message in queue file. Referring now to Figure 11, what is shown is a flow chart for the write or Qput operation. In this flow chart, upon having started as illustrated at 180, a block queue head pointer 182 effectively puts a lock on the head of the list so that no other user can access the head entry. Thereafter, the system increments the queue head pointer and sets the transaction state to "active read". This indicates the beginning of the handshaking process.
As illustrated at 186, the system then unlocks the queue head pointer and then, as illustrated at 188, reads the messages from the on-disk queue file. Thereafter, the QEM Table is locked as illustrated at 190, whereafter the log record is written as illustrated at 192 and the QEM Table is unlocked as illustrated at 194. The output of the unlock QEM Table step is referred to a decision block 196 which ascertains if the message transmission is transactional. If so, as illustrated at 198, the system runs a two-phase "commit" protocol to permit handshaking. This completes the Qput or write operation.
Referring now to Figure 12, a Qget or read operation is described. As can be seen, upon starting as illustrated at 200, the queue tail pointer is locked as illustrated at 202 and a new QEM entry is created with the queue tail pointer being incremented as illustrated at 204. Thereafter, as illustrated at 206, the system fills in the QEM entry control information and sets the transaction state to "active control" . Thereafter, as illustrated at 208, the queue tail pointer is unlocked and the QEM table is locked as illustrated at 210. Subsequently, as illustrated at 212, the system allocates on-disk blocks from the reservation table, with a block crossing a segment boundary being indicated at decision block 214. If the blocks cross segment boundaries, then as illustrated at 216, the system forces the QEMT check point write to disk. This refers to the fact of writing the in-memory copy to disk. It will be appreciated that block 206 updates the in-memory copy of the state of the QEM Table and thus the QEM entry. After having forced the QEMT check point write to disk as illustrated at 218, the system writes the message data to disk and unlocks the QEM Table. Decision block 220 establishes whether or not the messages is a transactional one and if so, runs a two phase commit protocol as illustrated at 221 to facilitate the handshaking. The end of the write sequence is illustrated at 222. It will be appreciated that block 220 refers to the receiver end running the handshaking protocol .
Referring now to Figure 13 , a recovery sequence is illustrated in which, upon starting as illustrated at 230, the queue table pointers are locked as illustrated at 232 and the system thereafter restores global data structure as illustrated at 234. This initializes the state of the system as a whole. Thereafter, as illustrated at 236 the system scans each QEMT in the queue file for the most recent QEMT. This establishes the most recent check point before communications interruption. Thereafter, as illustrated at 238, the system scans the log records in this segment for the log record with the latest QEMT. This means that the log records of the segment are applied to the messages referred to by the entries in the QEMT.
As illustrated at decision block 240, the system ascertains if there are more log records to scan. It will be appreciated that the QEMT specifies the most recent log record subsequent to the pointer associated with the QEMT in question. However, there may indeed be subsequent log records thereafter which need to be scanned. If this is the case, then the system contacts the participant about the transaction state of the message as illustrated at 242. In one instance, the receiver is queried as to whether it has received a message or not. Thereafter, the system invokes a two-phase "commit" protocol to resolve the transaction as illustrated at 244. This refers to the fact that the handshaking process is a two pass process. Thus, whatever state that one receives back from the receiver is used to restart the handshaking process at the point at which the system had failed. As can be seen at 246, the system updates the state of the reservation table and determines a new file pointer position. Thus, the entire section is scanned to update the state of reservation table 140, with the determination of the new file pointer position being established by the current segment number 130 and the next available block in the current segment 136.
As illustrated at 248, the system then writes out the new QEMT state to the disk at which point the recovery is complete as illustrated at 250.
As described hereinafter, the programming listing for one embodiment of the subject invention written in C follows:
* Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
* UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
* LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
* IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
* OR DISCLOSURE. *
* THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
* TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
* OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
+ EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA. *
* OpenMQ
* Module : qmam . c
* Author: David Wong 9/8/95
* Command Line Syntax: *
* C> qserv [-c] [-lq <name>] [-pq <name>] [-p <pathname>] \
* [-t <threads>] [-n <#qentπes>] [-e <#qextents>] \
* [-s <#segments>] *
* where [] = Optional flag.
* -c Create new queue file mode Will overwrite
* existing queue data and state files. If not
* set, then it is a restart caes .
* -lq = Logical queue name.
* -pq = Physical queue server name.
* -p Path of queue data and state files.
* -t Number of queue server threads to allocate.
* -n Number of queue entries to allocate for new queue
* -e Max number of additional extries that the queue
* can be extended to; not supported currently.
* -s = Number of segments to allocate for new queue. *
// Include Files //#mclude <memory.h> ttinclude "qlib.h" ttinclude "qserv. h" #ιnclude "qadmm.h"
lpQEMT MQEMT ; lpQSTR MQstate; lpOPSTATS MQops;
IpMTLIST Pendmg_TXNs = NULL ; int BLOCKS_PER_SEG; mt SEGMENT_SIZE ; int TOT_MSG_BLOCKS ; int QEMT_Sιze; int QEMT_Seq_No = 0 ; mt LREC_Seq_No = 0 ; int NUM_ΞEGS ; int MAX_ELMS ; int shdn_flag=0; int holey_entries=0; unsigned long QEME_TS = 1 ; lpLPG_TS_STR Last_Pending_Get ; lpLRCLST Active_LREC_List;
#define DefaultPath "C: \\Q\\QSERV" #define DefaultLogQue "Ql" #define DefaultPhyQue "QS1" #define Op_State "_Op_State" #define DefaultElms 100 #define DefaultExt 0 #define DefaultSegs 10 ttdefine DefaultThrs 1
#define Format "C> qserv [-.c] [-lq <name>] [-pq <name>] [-p <pathname>] [-t <thr
void Process_Msg( lpMSTR arg)
HANDLE hQSHDN_Event ; lpQHANDLE qhandle ; IpTSTR thr_str; SMBUF ENQ;
Diag("Queue Server Thread No. %d starting up ... " , arg- >thr_no) ;
// Open the queue for getting if (! (qhandle = Qopen (arg- >physical , GET_MODE, 0 , 0 , 0 , -1, 0) ) )
Fail ( "QServ_main: could not open queue server %s" , arg->physical) ; thr_str = (TSTR *) malloc (sizeof (TSTR) ) ; while ( (thr_str->Que_File_Handle=Open_Queue_File (arg->qname) )
== INVALID_HANDLE_VALUE) ; while (!shdn_flag && (QSUCCESS ==
QlistenBeforeReply (qhandle, &ENQ.msgh, ENQ. mdata, MAXMSGDATA) ) )
{ strcpy (thr_str->logical, arg->logical) ; strcpy (thr_str->physical, arg->physical) ; strcpy (thr_str->qname, arg->qname) ; strcpy (thr_str->qstate, arg->qsta e) ; thr_str->qhandle = qhandle; thr_str->lpsmbuf = &ENQ;
Diag ( " " ) ;
Diag ( "Request Serviced by QS Thread No. %d" , arg->thr_no) ; switch (ENQ.msgh .mode)
{ case PUT_MODE:
Diag( "DiskQ(%s) Queue Server in PUT_MODE" , arg->physical) ;
QS_QPut (thr_str) ; break; case REQUEST_MODE :
Diag ("DiskQ (%s) Queue Server in GET_MODE" , arg->physical) ; QS_QGet (thr_str) ; break; case ABORT_MODE: case COMMIT_MODE: if (ENQ. msgh. mode == ABORT_MODE)
Diag ( "DiskQ (%s) Queue Server in ABORT_MODE" , arg- >physical) ; else Diag ( "DiskQ (%s) Queue Server in COMMIT_MODE" , arg->physical) ; QS_QCommit (thr_str) ; break; case ADMI REQ_MODE :
Diag ( "DiskQ (%s) Queue Server in ADMINREQ_MODE" , arg- >physical ) ; QS_QAdmin(thr_str) ; if (shdn flag)
{ QreplyAfterListen (qhandle, ADMINREP_MODE, SUB_MODE_OK, 0,0,0) ;
// Qclose (NULL, arg->physical) ; Qclose (kqhandle, 0) ; hQSHDN_Event = OpenEvent (EVENT_MODIFY_STATE, TRUE, QSHDN_EVENT) ; if ( ! hQSHDN_Event )
Diag("QS_Admin: Can't OpenEvent for QS Shutdown"); if (SetEvent (hQSHDN_Event) == FALSE)
Diag( "QS_Admin: Can't SetEvent for QS Shutdown"); return;
} break; default :
Diag ( "DiskQ (%s) : Unexpected Mode=%d" , arg- >physical , ENQ . msgh . mode) ; QreplyAfterListen (qhandle, ACK MODE, SUB MODE BAD REQ, 0,0,0) ;
}
/*
Diag ("head = %d, tail = %d, pgets = %d, pputs = %d, segment = %d, block = %d",
MQEMT- >que_hd_ptr, MQEMT- >que_tl_ptr,
MQops->pending_ge s , MQops - >pending_puts ,
MQEMT- >next_avail_block . segment , MQEMT- >next_avail_block . block) ; print_RST() ; print_Active_Log_Lis () ; print QEME txn states (); */
// Sleep (3000) ,-
void main ( int argc, CHAR **argv) HANDLE Que_File__Handle;
HANDLE Que_State_Handle;
HANDLE hQHD , hQTL , hQEM ;
HANDLE hQEME , hLPG ;
HANDLE hMQstate , hMQops ;
HANDLE hQSHDN, hQSHDN_Event ;
HANDLE hTSM[MAX_QSERV_THREADS] ;
DWORD idTSM[MAX_QSERV_THREADS] ;
DWORD dwPointer;
DWORD dwBytesRead, dwBytesWritten; lpMSTR thr_arg [MAX_QSERV_THREADS] ;
BOOL Return_Status ; long temp_time; int seg_no; int i, status; int newq=0;
CHAR logical [NAMESIZE] =DefaultLogQue ;
CHAR physical [NAMESIZE] =DefaultPhyQue ;
CHAR path[QUE_FILE_SIZE] =DefaultPath;
CHAR quefile[QUE_FILE_SIZE] ;
CHAR qstate[QUE_FILE_SIZE] ;
CHAR buf [255] ; int max_elms=DefaultElms ; int ext_elms=Def ultExt ; int num_segs=DefaultSegs; int num_threads=DefaultThrs; int max_txns_per_seg;
i = 1; if ((argc > 1) && (! strcmp (argv [i] , " -c" )) )
{ newq = 1 ; i++;
while (i < argc) if (! strcmp (argv [i] , "-lq" ) )
{ i++ ; if (argv[i] [0] != '-') strcpy (logical, argv [i] ) ; else Diag ( "%s" , Format) ;
} else if (! strcmp (argv [i] ," -pq" ) )
{ i++; if (argv[i] [0] != '-') strcpy (physical, argv [i] ) ; else Diag (" %s ", Format ) ;
} else if (! strcmp (argv [i] ," -p" ) )
{ l++; if (argv[i] [0] != ' - ) strcpy (path, arg [i] ) ; else Diag ("%s" /Format) ; else if (! strcmp (arg [i] , " -t" ) )
{ i + + ; if (argv[i] [0] != '-') num_threads = atoi (argv [i] ) else Diag ( "%s" , Format) ;
} else if (! strcmp (argv [i] , " -n" ) )
{ i + +; if (argv[i] [0] != '-') max_elms = atoi (argv [i] ) ; else Diag (" %s ", Format ) ;
} else if (! strcmp (argv [i] ," -e" ) )
{ i + + ; if (argv[i] [0] != '-') ext_elms = atoi (argv [i] ) ; else Diag (" %s ", Format) ,-
} else if (! strcmp (argv [i] , " -s" ) )
{ i + + ; if (argv[i] [0] != '-') num_segs = atoi (argv [i] ) ; else Diag ( "%s" , Format) ;
i + +;
sprintf (quefile, "%s\\%s.dat" , ath, physical) ; sprintf (qstate, "%s\\%s . sta" , path, physical) ,-
// Check to see if QNETD is running, if ( !AttachSharedMemory ( ) )
Fail ("Error: QNETD is not running.");
// Create mutexes for protected data structures. hQHD = CreateMutex (NULL, FALSE, QUE_HD_PTR_LOCK) ; if (IhQHD)
Diag ("CreateMutex for Que Head Pointer lock failed."); hQTL = CreateMutex (NULL, FALSE, QUE_TL_PTR_LOCK) ; if (IhQTL)
Diag ("CreateMutex for Que Head Pointer lock failed."); hQEME = CreateMutex (NULL, FALSE, QEME_TS_GEN_LOCK) ; if (! hQEME)
Diag ("CreateMutex for QEME_TS Lock failed."); hLPG = CreateMutex (NULL, FALSE, LPG_TS_GEN_LOCK) ; if (IhLPG)
Diag ("CreateMutex for LPG_TS Lock failed."); hQEMT = CreateMutex (NULL, FALSE, QEMT_LOCK) ; if (! hQEMT)
Diag ("CreateMutex for QEM Table lock failed.");
hMQstate = CreateMutex (NULL, FALSE, MQstate_LOCK) ; if (! hMQstate)
Diag ( "CreateMutex for MQstate file lock failed."); hMQops = CreateMutex (NULL, FALSE, MQops_LOCK) ; if (! hMQops)
Diag ( "CreateMutex for MQops stats lock failed."); hQSHDN = CreateMutex (NULL, FALSE, QSHDN_LOCK) ; if (! hQSHDN)
Diag ( "CreateMutex for QShutdown lock failed."); hQSHDN_Event = CreateEven (NULL, RUE, FALSE, QSHDN_EVENT) if ( ! hQSHDN_Event )
Diag ( "CreateEvent for QShutdown event failed.");
// Allocate structure for queue shutdown // state and recovery statistics. MQstate = (QSTR * ) malloc (sizeof (QSTR) ) ;
// If new queue file get max_elms and num_segs
// from command line, else find most recent
// QEM table from disk. Policy is to delete
// existing quefile and qstate file when the
// -c flag is used. if (newq)
{ Que_File_Handle = Create_Queue_File (quefile, qstate, max_elms , num_segs) ■ while (Que File Handle == INVALID HANDLE VALUE)
{ " " " sprintf (buf , "del %s" , quefile) ; system (buf) ; sprintf (buf , "del %s ", qstate); system (buf) ;
Que__File_Handle = Create_Queue_File (quefile, qstate, max elms,num segs) ;
}
MAX_ELMS = max_elms; NUM SEGS = num segs;
} " " 26 else Que_File_Handle = Open_Queue_File (quefile) ; status = Find_Latest_QEM(Que_File_Handle, &MQEMT, &seg_no) ; print_QEMT (MQEMT, 1) ;
Return__Status = CloseHandle (Que_File_Handle) ;
MAX_ELMS = MQEMT- >max_entries ; NUM_SEGS = MQEMT- >num_segs;
Update QEME TS ( ) ;
Update_Globals ( ) ;
Last_Pending_Get = (LPG_TS_STR *) malloc (sizeof (LPG_TS_STR) ) ;
Last_Pending_Get->qeme_no = NIL; Last_Pendmg_Get->timestamp = 1 ;
// Theoretically possible to have MAX_ELMS // GET operations and txn termination log // records in same segment? max_txns_per_seg = MAX_ELMS ;
// max_txns_per_seg = 2*MAX_ELMS;
// max_txns_per_seg = (int) ceil ( (double) (MAX_ELMS/NUM_SEGS) ) ;
Active_LREC_Lιst = (LRCLST *) malloc (sizeof (LRCLST) ) ;
Active_LREC_List->max_txns_per_seg = max_txns_per_seg;
Active_LRΞC_List->address =
(int *) malloc (max_txns_per_seg*sizeof (int) ) ;
// Reinitialize the active log record list. Init_Active_LREC_Lis () ;
Que_State_Handle = Open_Queue_File (qstate) ;
// If new queue file, or if a restart clear, // case, initialize global data structures // and create new initial QEM Table, if (newq)
{ Status = Create_QEMT(&MQEMT,MAX_ELMS) ; status = Init_QEMT(MQEMT,MAX_ELMS,ext_elms,NUM_SEGS) ; status = Write_QEMT(Que_File_Handle, 0, MQEMT) ;
MQstate- >svr_state = QUEUE_ACTIVE;
MQstate- >num_restarts = 0;
MQstate->num_recov_tries = 0 ; temp_time = time (&MQstate->first_start_time) ; temp_time = time (&MQstate->last_restart_time) ;
MQstate- >last recov time = 0; else // Restart case.
{ // see if queue server shutdown cleanly last time dwPointer = SetFilePointer (Que_State__Handle,
0,NULL,FILE_BEGIN) ;
Return_Status = ReadFile (Que_State_Handle,
MQstate, sizeof (QSTR) , &dwBytesRead,NULL) ; if ( (Return_Status == FALSE) || (dwBytesRead != sizeof (QSTR) ) ) if (Return_Status == FALSE)
Diag ("status = FALSE"); Fail ("Main: Problem reading MQstate; BytesRead = %d" , dwBytesRead) ; }
MQstate- >num_restarts++; temp_time = time (&MQstate->last_restart_time) ;
// If queue server did not shutdown cleanly // last time, then run the recovery module, if (MQstate- >svr state == QUEUE ACTIVE)
{
MQstate->num_recov_tries++ ; MQstate->last_recov_time = temp_time; dwPointer = SetFilePointer (Que_State_Handle ,
0,NULL,FILE_BEGIN) ; Return_Status = WriteFile (Que_State_Handle,
MQstate, sizeof (QSTR) , &dwBytesWritten,NULL) ; if ( (Return_Status == FALSE) | |
(dwBytesWritten != sizeof (QSTR) ) )
{ if (Re urn_Status == FALSE)
Diag ("status = FALSE"); Fail ("Main: Problem writing MQstate; BytesWrtten = %d" , dwBytesWritten) ; }
QRecov(Que_File_Handle, seg_no) ;
MQstate- >num_recov_tries = 0; MQstate- >last recov time = 0;
} else // Clean shutdown last time; simple restart case.
{ MQstate->svr_state = QUEUE_ACTI E; MQEMT- >qget_state = ENABLED; MQEMT- >qput_state = ENABLED; if ( !Reconstruct_RST() )
Fail ("Restart procedure failed: cannot reconstruct RST");
. }
// update the queue s,erver state file dwPointer = SetFilePointer (Que State_Handle, 0 , NULL , FILE_BEGIN) ;
Return_Status = WriteFile (Que_State_Handle,
MQstate, sizeof (QSTR) , &dwBytesWritten,NULL) if ( (Return Status == FALSE) (dwBytesWritten sizeof (QSTR) ) if (Return_Status == FALSE)
Diag ("status = FALSE"); Fail ("Main: Problem writing MQstate; BytesWrtten = %d" , dwBytesWritten)
Return_Status = CloseHandle (Que_File_Handle) ; Return Status = CloseHandle (Que State Handle);
// initialize RT statistical counters MQops = (OPSTATS *) malloc (sizeof (OPSTATS) MQops- >num_gets = 0 ; MQops ->num_puts = 0 ; MQops ->num_aborts = 0 ; MQops- >num_commits = 0; MQops ->pending_gets = 0; MQops ->pending_puts = 0 ;
// do initial close to clear stale buffers Qclose (NULL, physical) ;
// spawn off worker threads i = 0; while (i < num threads)
{ thr_arg[i] = (MSTR *) malloc (sizeof (MSTR) ) ; strcpy (thr_arg [i] ->logical, logical) ; strcpy (thr_arg [i] ->physical, physical) ; strcpy (thr_arg[i] ->qname, quefile) ; strcpy (thr_arg [i] ->qstate, qstate) ; thr__arg [i] ->thr_no = i; hTSM[i] = CreateThread(NULL,0,
(LPTHREAD_START_ROUTINE) Process_Msg, thr_arg[i] , 0, kidTSM [i] ) ; i++; }
// Wait for shutdown to be signalled by a worker thread. // Add code later to check on status of worker threads. hQSHDN_Event = OpenEvent (SYNCHRONIZE, TRUE, QSHDN_EVENT) ; if ((status = WaitForSingleObjec (hQSHDN_Event, INFINITE) ) h
WAITJDBJECT_0 ) Diag("QS_Main: Synch wait for QS Shutdown Event failed"); II Clear memory buffers held by worker threads. // Need to wait for remaining replies to be sent // back before issuing Qclose.
Sleep(3000) ;
Qclose (NULL, hysical) ;
// Fetch all locks first. hQHD = OpenMutex (SYNCHRONIZE, FALSE, QUE_HD_PTR_LOCK) ; if (IhQHD)
Diag ("QS_Main: Can't OpenMutex for que head pointer lock"); if ((status = WaitForSingleObjec (hQHD,QUEJL0CKJTIMEOUT) ) !=
WAITJOBJECIJO )
Diag( "QS_Main: Synch wait for que head pointer lock failed"); hQTL = OpenMutex (SYNCHRONIZE, FALSE, QUE_TL_PTR_LOCK) ; if (IhQTL)
Diag("QS_Main: Can't OpenMutex for que tail pointer lock"); if ((status = WaitForSingleObject (hQTL, QUE_LOCK_TIMEOUT) ) !=
WAIT_OBJECT_0)
Diag ("QS_Main: Synch wait for que tail pointer lock failed"),- hQEME = OpenMutex (SYNCHRONIZE, FALSE, QEMEJTSJ3ENJLOCK) ; if (IhQEME)
Diag("QS_Main: Can't OpenMutex for QEMEJTS Lock"); if ((status = WaitForSingleObject (hQEME, QUE_LOCK_TIMEOUT) ) !=
WAIT_OBJECT_0)
Diag("QS_Main: Synch wait for QEMEJTS Lock failed"),- hLPG = OpenMutex (SYNCHRONIZE, FALSE, PG_TSJ3EN_L0CK) ; if (IhLPG)
Diag("QS_Main: Can't OpenMutex for LPG_TS Lock"); if ((status = WaitForSingleObject (hLPG, QUE_LOCK_TIMEOUT) ) !=
WAIT_OBJECT_0)
Diag("QS_Main: Synch wait for LPG_TS Lock failed"); hQEMT = OpenMutex (SYNCHRONIZE, FALSE, QEMT_LOCK) ; if (! hQEMT)
Diag("QS_Main: Can't OpenMutex for QEM Table lock"); if ((status = WaitForSingleObject (hQEMT, QUE_LOCK_TIMEOUT) ) !=
WAITJOBJECT_0 )
Diag("QS_Main: Synch wait for QEM Table lock failed"),- hQSHDN = OpenMutex (SYNCHRONIZE, FALSE, QSHDNJLOCK) ; if (! hQSHDN)
Diag("QS_Main: Can't OpenMutex for QSHDN lock"); if ( (status = WaitForSingleObject (hQSHDN, QUE_LOCK_TIMEOUT) ) ! =
WAIT_OBJECT_0)
Diag ( "QS_Main : Synch wait for QSHDN lock failed" ) ,- hMQstate = OpenMutex (SYNCHRONIZE , FALSE , MQstate_LOCK) ; if ( ' hMQstate )
Diag C'QSJMain : Can ' t OpenMutex for MQstate lock" ) ; if ( ( status = WaitForSingleObj ect (hMQstate , QUE_LOCK_ IMEOUT) ) ! =
WAITJOB JECT_0 )
Diag("QS_Main: Synch wait for MQstate lock failed") ; // write out last QEM Table before shutting down QueJFileJHandle = OpenJQueueJFile (quefile) ; status = GenJQEM_Seq_No (&MQEMT->qem_sn) ;
MQEMT- >next_availJblock . segment =
(MQEMT- >next_avail_block. segment+1) %MQEMT->num_segs; MQEMT- >next_availJblock. block = 0; status = Write_QEMT(QueJFile_Handle,
MQEMT- >next_availJblock . segment , MQEMT) ;
Return_Status = CloseHandle (QueJFileJHandle) ;
// Write out graceful shutdown state MQstate- >svr_state = QUEUE_SHUTDOWN;
Que_State_Handle = OpenJQueueJFile (qstate) ,- dwPointer = SetFilePointer (Que_State_Handle ,
0, NULL, FILEJBEGIN) ;
Return_Status = WriteFile (Que_State_Handle,
MQstate, sizeof (QSTR) , &dwBytesWritten,NULL) ; if ( (Return_Status == FALSE) || (dwBytesWritten != sizeof (QSTR) ) ) if (Return_Status == FALSE)
DiagC'status = FALSE"); Fail ( "QS_Main: Problem writing MQstate; BytesWritten = %d", dwBytesWritten) ; }
Return_Status = CloseHandle (Que_StateJHandle) ,-
SayC'Queue Server %s shuts down gracefully" , physical) ;
Sleep (3000) ;
// print_QEMT (MQEMT, 1) ;
// keep the locks to avoid worker // threads from writing to queue
/*
ReleaseMutex (hMQstate) ;
ReleaseMutex (hQSHDN) ;
ReleaseMutex (hQEMT) ,-
ReleaseMutex (hLPG) ,-
ReleaseMutex (hQEME) ;
ReleaseMutex (hQTL) ;
ReleaseMutex (hQHD) ; */ } User: root Host : bunny Class : bunny Job: stdin
* Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
* UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
* LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
* IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
* OR DISCLOSURE. *
* THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
* TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
* OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA. *
* OpenMQ
* Module: qrecov.c
* Author: David Wong 10/15/95 */
// Include Files ftinclude "qlib.h" ^include "qserv. h" #include "qadmin.h"
extern lpQEMT MQEMT; extern lpQSTR MQstate; extern lpMTLIST PendingJTXNs ; extern int BLOCKSJPER_SEG ; extern int SEGMENT_SIZE; extern int TO JMSGJBLOCKS ; extern int QEMT_Size,- extern int QEMT_Seq_No; extern int LREC_Seq_No; extern int NUM_SEGS ; extern int MAX_ELMS; extern unsigned long QEMEJTS;
//
// Recovery module basic algorithm:
// - lock queue table and head/tail ptrs
// - restore global data structures
// - fetch log records
// - determine state
// - contact client
// - invoke (partial) 2PC protocol
// - rollback bad cases
// - commit good cases
// - fix up reservation table
// - determine file ptr position
// - write new QEM Table out to disk
//
void QRecov (
HANDLE Que File Handle, int seq_no)
HANDLE hQHD, hQTL, hQEMT; lpMTLIST ThisJTXN;
LREC log_rec;
BOOL Return Status;
DWORD dwPointer;
DWORD dwBytesRead;
SN lrec no; int i, status;
hQHD = OpenMutex (SYNCHRONIZE, FALSE, QUE_HD_PTR_LOCK) ; if (IhQHD)
Diag ( "QS_QRecov: Can't OpenMutex for queue head pointer lock"); if ((status = WaitForSingleObject (hQHD, QUEJLOCKJTIMEOUT) ) != WAITJOBJECTJO )
Diag ( "QSJQRecov: Synch wait for queue head pointer lock failed"); ~
hQTL = OpenMutex (SYNCHRONIZE, FALSE, QUE_TL_PTRJLOCK) ; if (IhQTL)
Diag ( "QSJQRecov: Can't OpenMutex for queue tail pointer lock"); if ((status = WaitForSingleObject (hQTL, QUEJLOCKJTIMEOUT) ) != WAIT_OBJECT_0)
Diag ( "QSJQRecov: Synch wait for queue tail pointer lock failed"),- ~
hQEMT = OpenMutex (SYNCHRONIZE, FALSE, QUEJTLJPTR_LOCK) ,- if (! QEMT)
Diag ("QSJQRecov: Can't OpenMutex for QEM table lock"); if ((status = WaitForSingleObject (hQEMT, QUEJLOCKJTIMEOUT) ) != WAIT_OBJECT_r> *
Diag ( "QSJQRecov: Synch wait for QEM table lock failed");
// set file pointer to start of log records dwPointer = SetFilePointer (Que_File_Handle, seq_no*SEGMENT_SIZE,
NULL,FILE_BEGIN) ; dwPointer = SetFilePointer (Que_File_Handle,
QEMT_Size, NULL, FILE_CURRENT) ;
// Initialize log record timestamp, which is recorded
// in QEMT. Next, start reading the log records and
// construct extended pending txn list based on one
// fetched from QEMT. i = 0; lrec_no. timestamp = MQEMT->lrec_sn. timestamp; lrec_no. counter = MQEMT- >lrec_sn. counter; while (i<BLOCKS PER SEG)
{ ~ "
Return_Status = ReadFile (Que_File_Handle,
&log_rec, sizeof (LREC) , &dwBytesRead,NULL) ; i += LOG_REC_BLOCKS ; if (log_rec.marker != LRMARK) dwPointer = SetFilePointer (QueJFi leJHandle ,
(MSG_BODYJBLOCKS+LOG_RECJBLOCKS ) *BLOCK ,
NULL , FI E_CURRENT ) ; i += (MSG BODY BLOCKS +LOG REC BLOCKS ) ;
} " ~ " ~ e {lse if (Bigger-Seq-No(&log-rec.seq-no,&lrec-no))
// only need to be concern about log records // with increasing timestamps. lrec_no. timestamp = log_rec . seq_no . timestamp ; lrec_no. counter = log_rec . seq_no . counter;
// find txn in pending list
Return_Status = Find__MTlist (PendingJTXNs, &This_TXN, log_rec .mid) ; switch (log rec . txn_.state)
{ case PENDING: if (Return Status == TRUE)
{ Return_Status = FindJTlist (ThisJTXN- >ops , log_rec . qeme_no) ; if (Return_Status == FALSE)
Add Tlist(&This TXN->ops,log rec.qeme no);
} else
{
Add_MTlist (&PendingJTXNs , &This_TXN, log_rec.mid) ; Add Tlist(&This TXN->ops,log rec.qeme no);
} ~ break; case ABORT: case COMMIT: if (Return Status == TRUE)
{
Return_Status = DelJMTlist (&PendingJTXNs, log_rec .mid) ,- if (Return_Status == FALSE)
Diag( "QSJRecovery : Error deleting TID %d from Host %d", log rec .mid. tid, log rec .mid. host) ,-
} break; case EMPTY: break; default :
Diag ("QRecov: No such txn state"),- break; i 1
// now, resolve pending txns
QR Resolve PTL(Que FileJHandle) ;
// Flush out reconstructed QEMT to disk. // No need to find last known QEME offset. MQEMT- >next_availJblock . segment =
(MQEMT- >next_avail_block . segment+1) %MQEMT- >num_segs ;
MQEMT->next_availJblock. block = 0 ; status = Gen_QEM_Seq_No(&MQEMT->qem_sn) ; status = Write__QEMT(Que_File_Handle,
MQEMT- >next_avail_block . segmen ,
MQEMT) ;
// Reconstruct reservation table, if (! Reconstruct RSTO)
{
Diag ("Recovery procedure failed: cannot reconstruct RST");
ReleaseMutex (hQEMT) ,- .
ReleaseMutex (hQHD) ;
ReleaseMutex (hQTL) ,- return; }
MQEMT- >qget_state = ENABLED; MQEMT- >qput_state = ENABLED;
ReleaseMutex (hQEMT) ; ReleaseMutex (hQHD) ; ReleaseMutex (hQTL) ;
void QRJResolve_PT (
HANDLE Que File Handle)
{ " " lpQHANDLE qhandle; lpMTLIST ThisJTXN; lpTLIST This_TXN_ops; lpQEME lpqeme ; MSGH msgh, msgh2 ; int status;
ThisJTXN = PendingJTXNs ; while (This TXN != NULL)
{ This_TXN_ops = ThisJTXN- >ops,- status = CycleJQEME (ThisJTXN_ops->qeme_no, &lpqeme) ; status = Retrieve_Msg_Hdr (Que_File_Handle, lpqeme->offset , &msgh) ;
// get buffer for communication with QNETD if (! (qhandle = QopenReply (0, nsgh, 0 , "QNETD" , &status) ) ) Fail ("QS_QRecov: could not open connection to QNETD")
// check with Derek on proper use of inquiry msg if (QSUCCESS == QsendAndReceive (qhandle, ADMINREQ_MODE, QNETDJTRANJINQ,
0,0,0,0,0,0, &msgh2 ) )
{ while (This TXN ops != NULL)
{ if (msgh2. sub_mode == Q_COMMIT)
QRJResolveJTXNJO (ThisJTXN_ops->qeme_no, COMMIT) ; else QR_Resolve_TXNjOp(This_TXN_ops->qeme_no, ABORT) ;
This TXN ops = This TXN ops->next;
» ' " " else
{ Fail ("QSJQRecov: no response from QNETD"); Fail ("QSJQRecov: Queue Server ABORTS Transaction d" , ThisJTXN- >mid. tid) while (This TXN ops != NULL)
{ ~ "
QRJResolveJTXNJOp { This JTXN_ops->qeme_no, ABORT) ; This TXN ops = This TXN ops->next;
} " ~ '}
ThisJTXN = ThisJTXN- >next;
}
void QR_Resolve_TXNJO ( int qeme_no , short mode)
{ lpQEME lpqeme , lpqeme2 ; lpQEME hd_qeme , tl_qeme ,- int qeme_no2 ,- int status; status = CycleJQEME (qeme_no, &lpqeme) ; lpqeme->txn_state = mode; lpqeme->vote = mode;
// if txn is ABORTed, we need to rollback either // the queue head or tail pointer depending on // whether it's a GET/PUT op if (mode == COMMIT)
{ if (lpqeme->mode == GET MODE)
{ lpqeme->txn_state = EMPTY; lpqeme->vote = EMPTY;
» ' else // mode == ABORT { if (lpqeme->mode == PUT MODE)
{ lpqeme- >txn_state = EMPTY; lpqeme- >vote = EMPTY; if (qeme no == MQEMT- >que hd ptr)
{ if (MQEMT- >que hd ptr == MQEMT- >que tl ptr)
{ " ~
MQEMT- >que_hd_ptr = NIL;
MQEMT- >que tl ptr = NIL;
} ~ " else MQEMT->que hd ptr = (MQEMT->que hd ptr+1) %MQEMT->max entries;
} else if (qeme no == MQEMT- >que tl ptr)
{ qeme_no2 = qeme_no; lpqeme2 = lpqeme; while ( (lpqeme2->txn_state == EMPTY) && (qeme no2 != MQEMT->que hd ptr))
{ qeme_no2 = (MQEMT- >max_entries+qeme_no2 - l ) %MQEMT- >max_entries ; status = Cycle QEME (qeme no2 , &lpqeme2 ) ;
} if ( (qeme_no2 == MQEMT- >que_hd_ptr) && (lpqeme2->txn state == EMPTY))
{ MQEMT- >que_hd_ptr = NIL;
MQEMT- >que tl ptr = NIL;
} ~ " else MQEMT- >que_tl_ptr = qeme_no2 ,-
else // failed GET operation
{ // reset the op flag to a PUT lpqeme->mode = PUT_MODE; lpqeme->txn_state = COMMIT; lpqeme-> ote = COMMIT; if (MQEMT- >que__hd_ptr == NIL)
MQEMT->que_hd_ptr = qeme_no;
MQEMT- >que_tl_ptr = MQEMT- >que_hd_ptr; else
{ status = Cycle_QEME ( QEMT- >que_hd_ptr, &hd_qeme) ; status = Cycle_QEME (MQEMT- >que_tl_ptr, &tl_qeme) ; if ( lpqeme->timestamp < hd_qeme->timestamp) MQEMT- >que_hd_ptr = qeme_no; else if ( lpqeme->timestamp > tl_qeme->timestamp) MQEMT- >que tl ptr = qeme no;
" " " int Reconstruct_RST ()
{ lpRSTSEG lprstseg; lpQEME lpqeme ; mt *msg_block; mt qeme_no ,- mt l, ], status;
// Initialize the reservation table first, lprstseg = MQEMT- >rst_ptr- >seg_ptr ; for (1=0; 1<NUM_SEGS; 1++)
( msg_bloc = lprstseg- >msg_block; for (3=0, ]<MQEMT->rst ptr->msgs per_seg; η++)
{ *msg_block = NIL; msg block++;
} lprstseg++;
}
// Then, reconstruct it based on current QEMT state. qeme_no = MQEMT- >que_hd_ptr ,- while (qeme no != MQEMT- >que tl ptr)
{ status = Cycle_QEME (qeme__no, &lpqeme) ,- if (!Add RST Entry (lpqeme- >offse . segmen , lpqeme- >offset . block) )
{ " " Diag ("RST reconstruction phase failed, too many msgs in a segment". return (0) ; } qeme no = (qeme no+1) %MQEMT->max entries;
} " status = Cycle_QEME (qemejno, Slpqeme) ; if ( !Add RST Entry (lpqeme->offset . segment , lpqeme->offset .block) )
( " ~ Diag ("RST reconstruction phase failed: too many msgs in a segment"); return (0) ; }
for (ι=0, ι<MQEMT->num_segs; ι++) Sort_RSTjEntrιes (i) ; return (1) ; User: root Host : bunny Class: bunny Job: stdin
* Copyrigh (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
* UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
* LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
* IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
* OR DISCLOSURE. *
* THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
* TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
* OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
*
* OpenMQ
* Module: qsadmin.c
* Author: David Wong 10/15/95 */
// Include Files ^include "qlib.h" #include "qserv. h" #include "qadmin.h'
extern lpQEMT MQEMT ; extern lpQSTR MQstate; extern lpOPSTATS MQoos; extern lpMTLIST Pending TXNs ; extern int BLOCKS PER SEG; extern int SEGMENT SIZE; extern int TOT MSG BLOCKS; extern int QEMT Size; extern int QEMT_Seq_No ; extern int LREC Seq No; extern int MAX ELMS; extern int NUM_SEGS ; extern int shdn_flag; extern int holey entries; extern unsigned long QEME TS;
void QS QAdmin ι lpTSTR thr_arg)
{
HANDLE Que_File_Handle;
HANDLE Que_State_Handle;
HANDLE hQHD, hQTL, hQEMT;
HANDLE hMQstate, hMQops, hQSHDN;
DWORD dwPointer;
DWORD dwBytesRead;
DWORD dwBytesWritten;
MSGH msgh ,- lpQEME lpqeme ;
BLAD tblad;
CHAR buffer [MAXMSGDATA] ;
BOOL Return_Status; int done , found; int i , cnt , status ; int qeme_no ; int entry_num; time_t tempjtime ;
CHAR *t0, *tl,*t2, *t3; int *intO, *intl, *int2; short *shO, *shl, *sh2;
LONG Dist_to_Move;
QMSG qmsg2 ; lpMID mid; lpQMSG qmsg ; lpQADMSEL seldat; lpQADMSTATS lpstats; lpQADMCTLS Ctls; lpCNTSTR cnt_ptr=NULL; lpMLIST ml=NULL,m2=NULL,m3=NULL; lpMID midstrl=NULL,midstr2=NULL;
Que_File_Handle = thr_arg->Que_File_Handle ;
// Might have to fetched all locks if // we do not assume a quiescent state. switch (thr arg->lpsmbuf ->msgh. sub mode)
{ case QADM_REQ_STATS : lpstats = (QADMSTATS *) malloc (sizeof (QADMSTATS) ) ; strcpy ( lpstats ->logical_qname, thr_arg->logical) ,- strcpy ( lpstats ->physical_qname , thr_arg->physical) ; if (thr arg->qhandle != QUEUE TEST VALUE)
{ strcpy (lpstats->node_name, SHAREDATA (hostname) ) ,- lpstats- >node address = SHAREDATA (hostip) ,-
} lpstats- >max_entries_limit = MQEMT- >max_entries_limit ,- lpstats->max_entries = MQEMT- >max_entries; lpstats->pending_puts = MQops->pending_puts ; lpstats ->pending_gets = MQops->pending_gets; if (Check Queue Empty (MQEMT) == TRUE)
{ lpstats->committed_entries = 0; lpstats->holey_entries = 0; lpstats->num_free_entries = MQEMT->max_entries,- lpstats->amt free dspace = BLOCKS PER SEG*NUM SEGS*BLOCK;
} ~ " else
{ status = Find_Num_Entries (&cnt_ptr) ; lpstats- >committed_entries = cntjptr->committed; if (holey_entries == 0) lpstats- >holey_entries = cnt_ptr->holey; else lpstats->holey_entries = holey_entries ; lpstats->num_free_entries = MQEMT->max_entries- ( lps ats->committed_entries+lpstats->pending_gets+ lpstats->pending_puts+lpstats- holey_entries) ; lpstats- >amt_free_dspace = (int) ( ( (float) lpstats- >num_free_entries/ (float) QEMT- >max_entries) * TOT MSG BLOCKS*BLOCK) ;
} ~ "
lpstats->qget_state = MQEMT- >qget_state; lpstats->qput_state = MQEMT- >qput_state; lpstats ->num_puts = MQops->num_puts, lpstats ->num_gets = MQops->num_gets, lpstats ->num_aborts = MQops ->num_aborts ,- lpstats->num_commits = MQops- >num_commits ; lpstats->num_restarts = MQstate- >num_restarts ; lpstats- >first_start_time = MQstate- >first_start_time ; lpstats- >last_restart_time = MQstate- >last_restart_time; if (thr_arg->qhandle != QUEUEJTESTJVALUE)
QreplyAfterListen (thr_arg->qhandle,ADMINREP_MODE,SUB_MODE_OK,
(char *) lpstats, sizeof (QADMSTATS) , 0) ;
free (lpstats) ; if (cnt_ptr != NULL) free (cnt_ptr) ; break ,-
case QADM_SET_CONTROLS : ctls = (IpQADMCTLS) thr_arg- >lpsmbuf ->mdata;
// Enable/Disable QGETs and QPUTs hQEMT = OpenMutex (SYNCHRONIZE, FALSE, QEMT_LOCK) ; if (!hQEMT)
Diag("QS_Admin: Can't OpenMutex for QEM Table lock"); if ((status = WaitForSingleObject (hQEMT, QUE_LOCK_TIMEOUT) ) !=
WAIT_OBJECT_0)
Diag("QS_Admin: Synch wait for QEM Table lock failed"); if (ctls- >enable_qputs_flag) MQEMT- >qput_state = ENABLED; else MQEMT->qpUt_state = DISABLED; if (ctls->enable_qgets_flag) MQEMT- >qget_state = ENABLED; else MQEMT- >qget_state = DISABLED;
ReleaseMutex (hQEMT) ;
if (ctls->stats reset flag)
{ hMQops = OpenMutex (SYNCHRONIZE, FALSE, MQops_LOCK) ; if (! hMQops)
Diag("QS_Admin: Can't OpenMutex for MQops stats lock"); if ((status = WaitForSingleObject (hMQops, QUEJLOCKJTIMEOUT) ) ! = WAITJOBJECTJO) Diag ( "QS_Admιn: Synch wait for MQops stats lock failed");
MQops ->num_puts = 0; MQops ->num_gets = 0; MQops ->num_aborts = 0; MQops ->num_commιts = 0;
ReleaseMutex (hMQops) ;
// full reset clear stat counters and queue entries if (ctls->full reset flag)
{ // Fetch all locks first hQHD = OpenMutex (SYNCHRONIZE, FALSE, QUE_HD_PTR_LOCK) , if (IhQHD)
Diag ( "QS_Admm . Can't OpenMutex for que head pointer lock"); if ((status = WaitForSingleObject (hQHD, QUE_LOCK_TIMEOUT) ) !=
WAITJOBJECTJO) Diag ( "QS_Admm : Synch wait for que head pointer lock failed"] hQTL = OoenMutext SYNCHRONIZE, FALSE, QUE_TL_PTR_LOCK) , if (IhQTL)
Diag ( "QS_Admιn : Can't OpenMutex for que tail pointer lock"), if ((status = WaitForSingleObject (hQTL, QUEJLOCKJTIMEOUT) ) !=
WAITjOBJECT_0)
Diag ( "QS_Admιn Synch wait for que tail pointer lock failed"] hQEMT = OpenMute (SYNCHRONIZE, FALSE, QEMTJLOCK) , if (! hQEMT)
Dιag( "QS_Admm Can't OpenMutex for QEM Table lock"), if ((status = WaitForSingleObjec (hQEMT, QUEJLOCKJTIMEOUT) ) '=
WAIT_OBJECT_0)
Dιag( "QS_Admm: Synch wait for QEM Table lock failed"), hQSHDN = OpenMute (SYNCHRONIZE, FALSE, QSHDN_LOCK) , if (! hQSHDN)
Dιag( "QS_Admm: Can't OpenMutex for QSHDN lock"); if ((status = WaitForSingleObjec (hQSHDN, QUE_LOCK_TIMEOUT) ) !=
WAIT JDB JECTJO )
Dιag("QS_Admιn: Synch wait for QSHDN lock failed"),- hMQstate = OpenMutex (SYNCHRONIZE, FALSE, MQstateJLOCK) ; if (IhMQstate)
Diag ( "QS_Admm: Can't OpenMutex for MQstate lock"), if ((status = WaitForSingleObjec (hMQstate, QUEJLOCKJTIMEOUT) )
WAIT_OBJECT_0 )
Diag ( "QS_Admιn. Synch wait for MQstate lock failed"), hMQops = OpenMutex (SYNCHRONIZE, FALSE, MQops_LOCK) ; if (! hMQops)
Diag ("QS_Adrnm. Can't OpenMutex for MQops stats lock"), if ((status = WaitForSingleObject (hMQops, QUE_LOCK_TIMEOUT) ) '=
WAITJOBJECTJO)
Dιag("QS_Admm: Synch wait for MQops stats lock failed"),
// Clear queue and pending txn list and // write out initialized QEM table. DelJMTlιst_All (&Pendιng_TXNs) ,-
Inιt_Actιve_LREC_List () ; status = ImtjQEMT (MQEMT, MQEMT- >max_entrιes,
MQEMT- >max_entrιes_lιmι , MQEMT->num_segs) ;
status = WriteJQEMT (QueJFileJHandle, 0, MQEMT) ;
// Reset all stat counters. MQops ->num_puts = 0; MQops ->nuπ gets = 0, MQops- >num_aborts = 0 ; MQops ->num_commιts = 0; MQops- >pendmg_puts = 0; MQops ->pendιng_gets = 0 ;
// Dump out queue state info. MQstate- >num_restarts = 0; MQstate- >num_recovjtrιes = 0; tempjtime = time f&MQstate- >last_restart_tιme) MQstate->last recov time = 0 ,-
Que_StateJHandle = OpenjQueue_Fιle (thr_arg->qstate) ; dwPointer = SetFilePointer (Que_State_Handle ,
0, NULL, FILEJBEGIN) ;
Retum_Status = WriteFile (Que_StateJHandle ,
MQstate , sizeof (QSTR) , &dwBytesWrιtten,NULL) ; if ((Return Status == FALSE) II (dwBytesWritten != sizeof (QSTR) )
{ prmtf ( "QS_Admιn: Problem writing out MQstate . \n" ) ; prmtf ( "BytesWritten = %d\n" , dwBytesWritten) ; f (Return_Status == FALSE) prmtf ("status = FALSE\n");
Return_Status = CloseHandle (Que_State_Handle) ;
QreplyAfterListen (thr_arg->qhandle, ADMINREP_MODE, SUBJMODE_OK,0,0,0) ;
ReleaseMutex (hMQops) ; ReleaseMutex (hMQstate) ; ReleaseMutex (hQSHDN) ; ReleaseMutex (hQEMT) ; ReleaseMutex (hQTL) ; ReleaseMute (hQHD) ;
(ctls->shutdown_flag) // Fetch all locks first hQHD = OpenMutex (SYNCHRONIZE, FALSE, QUE_HD_PTR_LOCK) , f ChQHD)
Diag ( "QS_Adm n Can't OpenMutex for que head pointer lock"), if ((status = WaitForSingleObject (hQHD, QUE_LOCK_TIMEOUT) ) '=
WAITJDBJECTJO)
Diag ( "QS_Admm Synch wait for que head pointer lock failed"), hQTL = OpenMutex (SYNCHRONIZE, FALSE, QUE_TL_PTR_LOCK) , if ('hQTL)
Diag ( "QS_Adm Can't OpenMutex for que tail pointer lock"), if ((status = WaitForSingleObject (hQTL, QUE_LOCK_TIMEOUT) ) ι=
WAITJDBJECTJO)
Diag ( "QS_Admm Synch wait for que tail pointer lock failed"), hQEMT = OpenMutex (SYNCHRONIZE, FALSE, QEMT_LOCK) , if ('hQEMT)
Diag ("QS_Admm Can't OpenMutex for QEM Table lock"), if ((status = WaitForSingleObject (hQEMT, QUE_LOCK_TIMEOUT) ) > =
WAIT_OBJΞCTJ0)
D a ( "QS_Admm Synch wait for QEM Table lock failed"), hQSHDN = OpenMutex (SYNCHRONIZE, FALSE, QSHDN_LOCK) , if ('hQSHDN)
Diag ( "QS_Admm Can't OpenMutex for QSHDN lock"), if ((status = WaitForSingleObject (hQSHDN, QUEJLOCKJTIMEOUT) ) '=
WAITJOBJECT_0)
Dιag("QS_Admm Synch wait for QSHDN lock failed"),
// Disable GETs/PUTs and set shutdown flag MQEMT- >qget_state = DISABLED, MQEMT- >qput_state = DISABLED, shdrjflag = 1,
ReleaseMutex (hQSHDN) , ReleaseMutex (hQEMT) , ReleaseMutex (hQTL) , ReleaseMutex (hQHD) , } break,
case QADMjREQ_COMJDATA // retrieve msg based on QEM entry# case QADM_REQ_UNCOM_DATA entry_num = (mt) *thr_arg->lpsmbuf ->mdata, found = 0 , f (Check Queue Empty (MQEMT) == FALSE)
{ 1 = 0, qeme no = MQEMT- >que_hd_ptr , status = CycleJQEME (qeme_no, &lpqeme) , done = 0 , while ( 'done) if ( ( (thr_arg->lpsmbuf->msgh.sub_mode == Q DMJREQ_COMJDATA) && ( lpqeme- >txn_state == COMMIT) ) | |
( (thr_arg->lpsmbuf->msgh.sub_mode == QADM_REQ_UNCOM_DATA) && ( (lpqeme- >txn_state == ACTIVE) | | (lpqeme->txn state == PENDING))))
{ if (i == entry num)
{ done = 1 ; found = 1;
} else if (i > entry_num) done = 1 ,- else if (i < entry_num) i++;
} if ( ! done)
{ if (qeme_no == MQEMT- >quejtl_ptr) done = 1 ,- else
{ qeme_no = (qeme_no+l) %MQEMT- >max_entries ; status = Cycle QEME (qeme no, klpqeme) ,-
} // end while } // end if CheckJQueueJEmpty ( )
if (found)
{ status = Retrieve «lsgJHdr (QueJFileJHandle, lpqeme- >offset , kmsgh) ; tblad. segment = lpqeme- >offset . segment ; tblad. block = lpqeme- >offset . block+MSG_HDRJBLOCKS; status = Retrieve_MsgJBody (QueJFileJHandle, tblad, msgh. size, buf fer) ,- QreplyAfterListen ( hr_arg- >qhandle , ADMINREP_MODE , SUB_MODE_OK, buf fer , msgh. size, &msgh) ,-
} else // bad queue entry number
( Diag( "QS_Admin: Queue Entry %d is Invalid" , entry_num) ; QreplyAfterListen (thr arg->qhandle, ADMINREP_MODE, 0 , 0 , 0 , 0) ;
} break;
case QADMJREQ_SELJDATA : // retrieve list of MIDs based on key search seldat = (QADMSEL * ) thr_arg- >lpsmbuf ->mdata; tO = (CHAR *)malloc (sizeof (QMSG) ) ; if (CheckJQueueJEmpty (MQEMT) == FALSE) qeme_no = MQEMT- >que_hd_ptr, status = CycleJQEME (qeme_no, Slpqeme) , ml = (MLIST *) malloc (sizeof (MLIST) ) , ml->next = NULL, ml~>mιd. host = 0, ml->mιd tid = 0, ml->mιd.u d = 0, m2 = ml , done = 0 , while ( ' done)
{ found = 0 , if ( (seldat->searchjtype == SEARCH_ALL_ENT) | | ( (seldat->searchjtype == SEARCH_COM_ENT) && (lpqeme->txn_state == COMMIT)) || ( (seldat->search_type == SEARCH_UNCOM_ENT) && ( ( lpqeme- >txn_state == ACTIVE) | | (lpqeme->txn state == PENDING))))
{ Conv_Addr (&DιstJtoJMove, &lpqeme->offset ) , dwPointer = SetFilePointer (QueJFileJHandle ,
Dιst_to_Move, NULL, FILEJBEGIN) ,
Return_Status = ReadFile (QueJFileJHandle, tO, sizeof (QMSG) , &dwBytesRead,NULL) , tl tl [0] offset, if ] .predjtype == INT_SEARCH_TYPE)
Figure imgf000050_0001
else if (seldat->preds [0] .predjtype == SHORT__SEARCH_TYPE) shO = (short *)tl, if (seldat->num preds > 1)
{ t2 = tO, t2 += seldat->preds [1] .offset , if (seldat->preds [1] .predjtype == INT_SEARCHJTYPE) inti = ( t *)t2; else if (seldat->preds [1] predjtype == SHORT_SEARCH_TYPE) shl = (short *)t2, if (seldat->num preds > 2)
{ t3 = tO, t3 += seldat->preds [2] .offset , if (seldat->preds [2] .predjtype == INT_SEARCH_TYPE) mt2 = (mt *)t3, else if (seldat->preds [2] .predjtype == SHORT_SEARCH_TYPE) sh2 = (short *)t3, switch (seldat- >num_preds) case 1 : if ( ( ! seldat->preds [0] .mm_swιtch ||
(( (seldat ->preds [0] .predjtype == INT_SEARCH TYPE) && (*ιnt0 >= seldat - >preds [0] .mm_mt_val) ) J| ( (seldat ->preds [0] .predjtype == SHORT_SEARCHJTYPE) &&
(*shO >= seldat - >preds [0] .mm_sh_val) ) || ( (seldat ->preds [0] .predjtype == STR_SEARCHJTYPE) && (strncmp (tl, seldat ->preds [0] . mm_str_val, seldat->preds [0] . mm_str_len) >= 0)))) &&
( ! seldat->preds [0] .max_switch | |
(( (seldat->preds [0] .predjtype == INT_SEARCH TYPE) && (*mtO <= seldat->preds [0] .max_ιnt_val) ) ~|~| ( (seldat->preds [0] .predjtype == SHORT_SEARCH_TYPE) &&
(*shO <= seldat - >preds [0] .max_sh_val) ) || ( ( seldat ->preds [0] .pred_type == STR_SEARCH_TYPE) && (strncmp (tl, seldat- preds [0] . max_str_val , seldat->preds [0] .max_str_len) <= 0))))) found = 1; break;
case 2. if ( ( ! seldat->preds [0] .mm_swιtch | |
(( (seldat->preds [0] .predjtype == INT_SEARCH TYPE) && (*mt0 >= seldat->preds [0] .mm_mt_val) ) J| ( (seldat->preds [0] .predjtype == SHORT_SEARCHJTYPE) &&
(*sh0 >= seldat->preds [0] . mm_sh_val) ) | | ( (seldat ->preds [0] .predjtype == STR_SEARCH_TYPE) && (strncmp ( l , seldat ->preds [0] . mιn_str_val , seldat->preds [0] mm_str_len) >= o)))) &&.
( ! seldat->preds [0] .max_swιtch | |
(( (seldat->preds [0] .predjtype == INT_SEARCH TYPE) && (*mt0 <= seldat- >preds [0] .max_mt_val) ) J| ( (seldat ->preds [0] .pred_type == SHORT_SEARCH_TYPE) &&
(*sh0 <= seldat->preds [0] .max_sh_val) ) | | ( (selda ->preds [0] .predjtype == STR_SEARCH_TYPE) && (strncmp (tl, seldat- >preds [0] .max_str_val, seldat->preds [0] .max_str_len) <= 0)))) &&
(! selda ->preds [1] .min_swιtch | |
(( (seldat->preds [1] .predjtype == INT_SEARCH TYPE) && (*mtl >= seldat->preds [1] .mm_mt_val) ) ~[ | ( (seldat ->preds [1] .predjtype == SHORT_SEARCHJTYPE) &&
(*shl >= seldat - >preds [1] .mm_sh_val) ) | | ( ( seldat ->preds [1] .pred_type == STR__SEARCH_TYPE) && (strncmp (t2, seldat ->preds [1] .mm_str_val, seldat->preds [1] .mm_str_len) >= 0)))) &&.
( ! seldat->preds [1] .max_swιtch | |
( ( (seldat->preds [1] .pred_type == INT_SEARCH TYPE) && (*mtl <= seldat->preds [1] .max_mt_val) ) ~[~| ( (seldat ->preds[l] .predjtype == SHORT_SEARCH_TYPE) &&
(*shl <= seldat->preds [1] .max_sh_val) ) | | ( (seldat ->preds[l] .predjtype == STR_SEARCH_TYPE) && (strncmp (t2 , seldat ->preds [1] .max_str_val, seldat->preds [1] .max_str_len) <= 0))))) found break,
case 3 if ( ( ! seldat->preds [0] .m n_swιtch ||
(seldat - >preds [0] .predjtype == INT_SEARCH TYPE) && (*ιnt0 >= seldat->preds [0] .mιn_ιnt_val) ) J| (seldat->preds [0] .pred_type == SHORT_SEARCHJTYPE) && (*sh0 >= seldat - >preds [0] .mιn_sh_val) ) || (seldat->preds [0] .predjtype == STR_SEARCH_TYPE) && (strncmp ( tl , seldat ->preds [0] .mm_str_val , seldat->preds [0] .mιn_str_len) >= 0)))) && seldat->preds [0] .max_swιtch | |
(seldat->preds [0] .predjtype == INT_SEARCH TYPE) &&
(*mt0 <= seldat - >preds [0] .max_mt_val) ) J|
( seldat - >preds [0] .predjtype == SHORT_SEARCH_TYPE) &&
(*sh0 <= seldat - >preds [0] .max_sh_val) ) ||
(seldat->preds [0] .pred_type == STR_SEARCH_TYPE) &&
(strncmp (tl , seldat ->preds [0] . max_str_val, seldat->preds [0] .max_str_len) <= 0)))) && seldat- >preds [1] . mιn_swιtch | |
( seldat - >preds [1] .predjtype == INT_SEARCH TYPE) &&
(*mtl >= seldat- >preds [1] . mιn_ιnt_val) ) ~|~ |
(seldat->preds [1] .predjtype == SHORT_SEARCH_TYPE) &&
(*shl >= seldat - >preds [1] .mm_sh_val) ) ||
( seldat - >preds [1] .predjtype == STR_SEARCH_TYPE) &&
(strncmp (t2 , seldat->preds [1] . m n_str_val , seldat->preds [1] .mιn_str_len) >= 0)))) && seldat->preds [1] max_swιtch | |
(seldat->preds [1] .predjtype == INT_SEARCH TYPE) S
(*mtl <= seldat->preds [1] . max_ιnt_val) ) J|
(selda - >preds [1] .predjtype == SHORT_SEARCH_TYPE) &&
(*shl <= seldat - >preds [1] .max_sh_val) ) ||
(seldat->preds [1] .pred_type == STR_SEARCH_TYPE) &&
(strncmp (t2 , seldat->preds [1] . max_str_val, seldat->preds [1] .max_str_len) <= 0)))) && seldat->preds [2] .mm_swιtch | |
(seldat- >preds [2] .predjtype == INT_SEARCH TYPE) &&
(*ιnt2 >= seldat ->preds [2] .mm_mt_val) ) J|
(seldat- >preds [2] .predjtype == SHORT_SEARCHJTYPE) &&
(*sh2 >= selda ->preds [2] .mm_sh_val) ) ||
(seldat->preds [2] .predjtype == STR_SEARCH_TYPE) &&
(strncmp (t3 , seldat- >preds [2] . mιn_str_val, seldat->preds [2] .mm_str_len) >= 0)))) &&
( ! seldat->preds [2] .max_swιtch ||
(( (seldat->preds [2] .predjtype == INT_SEARCH TYPE) && (*ιnt2 <= seldat- >preds [2] .max_mt_val) ) J| (seldat->preds [2] .predjtype == SHORT_SEARCH_TYPE) && (*sh2 <= seldat- >preds [2] .max_sh_val) ) || (seldat->preds [2] .predjtype == STR_SEARCH_TYPE) && (strncmp (t3, seldat ->preds [2] . max_s r_va1 , seldat->preds [2] .max_str_len) <= 0))))) found =.'l; break, default : break; } // end switch
} // endif
if (found)
{ m3 = (MLIST *) malloc (sizeof (MLIST) ) ; m3->next = NULL; m2->next = m3 ; m2 = m3 ; qmsg = (QMSG *)t0; m3->mid.host = qmsg->Msg_Hdr .mid. host ,- ■ m3->mid.tid = qmsg- >Msg_Hdr .mid . tid, m3->mid.uid = qmsg->Msg Hdr .mid. uid; } if (qeme_no == MQEMT- >que_tl_ptr) done = 1 ; else
{ qeme_no = (qeme_no+l) %MQEMT->max_entries ,- status = Cycle QEME (qeme no, klpqeme) ;
} } // end while
} // end if CheckJQueueJEmpty ( )
if (ml != NULL)
{ m2 = ml ; ml = ml->next; m2->next = NULL; free (m2) ; } if (ml == NULL)
{ Diag ( "QS_Admin: No match on predicate"),- QreplyAfterListen (thr arg->qhandle, ACK MODE, SUB MODE EMPTY, 0,0,0)
} else
{ cnt = 0 ; m2 = ml ; while (m2 != NULL)
{ cnt++; m2 = m2 - >nex ; } midstrl = (MID *) malloc (cnt*sizeof (MID) ) ; m2 = ml ; midstr2 = midstrl; while (m2 != NULL)
{ midstr2->host = m2->mid.host; midstr2->tid = m2->mid. tid; midstr2->uid = m2->mid.uid; m2 = m2->next; midstr2++; }
QreplyAfterListen ( thr_arg- >qhandle , ADMINREP_MODE , SUB_MODEJOK,
(char *) midstrl, cnt*sizeof (MID) ,0) ; }
// free up memory to clean up memory leaks free (tO) ; if (midstrl != NULL) free (midstrl) ,- while (ml != NULL)
{ m2 = ml ,- ml = ml->next; m2->next = NULL; free (m2) ; } break;
case QADMJREQ_MSG : // retrieve msg based on MID mid = (MID *) thr_arg->lpsmbuf ->mdata; status = FindJQEME (mid, &qeme_no, &lpqeme) ; if (status == QSUCCESS)
{ Conv_Addr (&DistJto_Move , klpqeme ->offse ) ; dwPointer = SetFilePointer (QueJFile_Handle,
DistJto_Move , NULL,FILEJBEGIN) ;
Return_Status = ReadFile (QueJFileJHandle,
&qmsg2 , sizeof (QMSG) , &dwBytesRead,NULL) ,-
QreplyAfterListen ( thr_arg- >qhandle , ADMINREP_MODE , SUBJODEJOK, qmsg2. MsgJBody . text, qmsg2.MsgJHdr . size, &qmsg2.Msg Hdr) ;
} else
{
Diag ("QS_Admin: No msg with such MID");
QreplyAfterListen ( thr arg- >qhandle , ACKJMODE , SUB_MODEJEMPTY, 0,0,0) } break;
default :
Diag ( "QS_Admin: Option %d Not Valid" , thr_arg- >lpsmbuf- >msgh . sub_mode)
/* * Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
* UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
* LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
* IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
* OR DISCLOSURE.
*
* THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
* TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
* OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
*
* OpenMQ
* Module: qscommit.c
* Author: David Wong 9/8/95
* /
// Include Files #include "qlib.h" #include "qserv. h" #include "qadmin.h"
extern lpQEMT MQEMT; extern lpQSTR MQstate; extern lpOPSTATS MQops; extern lpMTLIST Pending TXNs; extern int BLOCKS PER SEG; extern int SEGMENT SIZE; extern int TOT_MSG_BLOCKS ; extern int QEMT Size; extern int QEMT SeqJSTo; extern int LREC Seq No; extern int NUM SEGS; extern int MAX ELMS;
void QS_QComm.it ( lpTSTR thr_arg)
HANDLE Que_File_Handle;
HANDLE hQEMT, hMQops ;
BLAD tblad;
BOOL Return_Status ; lpMTLIST ThisJTXN; lpTLIST This_TXN_ops;
IpSMBUF lpsmbuf;
LREC log_rec; short mode; int status; int tgets=0, tputs=0; int count=0;
Diag ( "DiskQ (%s) : Termination for TID: %d from Host: %x" , thr_arg->qname, thr_arg->lpsmbuf- >msgh . mid .tid, thr_arg- >lpsmbuf->msgh .mid.host) ; /*
Diag ( » » ) ;
Diag ( "MID . host = %x" , thr_arg- >lpsmbuf - >msgh . mid . host ) ;
Diag C'MID . tid = %d" , thr_arg- >lpsmbuf - >msgh . mid . tid) ;
Diag ( "MID . uid = %d" , thr_arg- >lpsmbuf - >msgh . mid . uid) ;
Diag C " ) ; print_PTList () ;
Diag ( » " ) ;
*/ lpsmbuf = thr_arg->lpsmbuf ; if (lpsmbuf->msgh.mode == COMMIT_MODE) mode = COMMIT; else mode = ABORT;
Return_Status = Find_MTl,ist (PendingJTXNs, &This_TXN, lpsmbuf->msgh.mid) ,- if (Return Status == FALSE)
{ Diag("QS_Commit : TXN %d from Host %x does not exist", lpsmbuf->msgh. mid. tid, lpsmbuf->msgh.mid. host) ; if (thr_arg->qhandle != QUEUEJTESTJVALUE)
QreplyAfterListen (thr_arg->qhandle, ACK_MODE, SUB_MODE_INV_TID, 0,0,0) ; else
{
// first, update the entries in the // QEM Table for each op in txn This_TXN_ops = ThisJTXN- >ops; while (This_TXN_ops != NULL)
QS_Resolve_TXN_Op (This_TXN_ops->qeme_no, fctgets, &tputs,mode) ,-
This_TXN_ops = This_TXN_ops->next; count++; // increment txn ops counter }
// delete TID op list from pending txn list
Return_Status = Del_MTlist (&Pending_TXNs, lpsmbuf->msgh.mid) ; if (Return_Status == FALSE)
Diag("QS_Commit: error deleting TID %d from Host %d", log_rec.mid. tid, log_rec.mid. host) ;
// then, write ABORT/COMMIT log record Que_File_Handle = thr_arg->Que_File_Handle; hQEMT = OpenMutex (SYNCHRONIZE, FALSE, QEMT_LOCK) ; if (!hQEMT)
Diagf'QSjQCommit: Can't OpenMutex for QEM Table lock"); if ((status = WaitForSingleObject (hQEMT, QUE_LOCK_TIMEOUT) ) !=
WAIT_OBJECTJO) Diag("QS_QCommit: Synch wait for QEM Table lock failed"); log_rec.marker = LRMARK; status = Gen_LREC_Seq_No(&log_rec.seq_no) ; 8/21654
log_rec.mode = mode; log_rec . flags = lpsmbuf->msgh. flags ; log_rec . qeme_no = NIL; log_rec. txn_state = mode; log_rec.vote = mode; log_rec.mid.host = lpsmbuf->msgh.mid. host ; log_rec .mid. tid = lpsmbuf->msgh. mid. tid; log_rec.mid.uid = lpsmbuf->msgh. mid.uid; log_rec.offset . segment = NIL; log_rec .offse .block = NIL;
// Fetch next available on-disk slot for log write. if{ (!Get_Next_BLAD(Que_File_Handle, LOG WRITE, &tblad) )
// queue data file is full or too fragmented.
Diag ( "DiskQ (%s) is either full or too fragmented. ", thr_arg->qname) ,- if (thr_arg->qhandl,e != QUEUEJTESTJVALUE)
QreplyAfterListen (thr_arg->qhandle, ACKJMODE,
SUB_MODE_FULL,0,0,0) ;
ReleaseMutex (hQEMT) ,- return,- } status = Write_Log_Rec (Que_File_Handle, tblad, &log_rec) ,- ReleaseMutex (hQEMT) ;
// send ACK msg back to client if (thr_arg->qhandle != QUEUE_TEST_VALUE)
QreplyAfterListen (thr_arg- >qhandle, ACK_MODE, SUB_MODE_OK, 0,0,0) ,-
// update RT stastical counters hMQops = OpenMutex (SYNCHRONIZE, FALSE, MQops_LOCK) ; if (! hMQops)
Diag( "QS_QCommit : Can't OpenMutex for MQops stats lock"); if ((status = WaitForSingleObject (hMQops, QUE_LOCK_TIMEOUT) ) !=
WAIT_OBJECTJO) Diag( "QS_QCommit : Synch wait for MQops stats lock failed"); if (mode == ABORT)
MQops->num_abor s += count; else MQops->num_commits += count;
MQops- >pending_gets = MQops->pending_gets-tgets, MQops->pending_puts = MQops->pending_puts-tputs;
ReleaseMutex (hMQops) ; } void QS_Resolve_TXN_Op ( mt qeme no , mt *tgets , mt *tputs , short mode )
{ lpQEME lpqeme ; mt status; status = Cycle_QEME (qeme_no, klpqeme) ,-
// increment number of pending GET/PUT // to decrement from MQops counter. if ( lpqeme - >mode == GET_MODE) (*tgetsj ++; else if (lpqeme- >mode == POTJMODE) (*tputs) ++ ; lpqeme->txn_state = mode; lpqeme- >vote = mode; f (mode == COMMIT)
{ if ( lpqeme- >mode == GET MODE)
{ lpqeme- >txn_state = EMPTY, lpqeme- >vote = EMPTY; if ( !Del_RSTJEntry ( lpqeme- >offse . segmen , lpqeme- >o fse . block) '
Diag ( "QS_QComm : Problem with deleting entry from reservation table"/,
SortJRST_Entrιes ( lpqeme ->offset . segment) ,
} else // ABORTed txn.
{ if (lpσeme->mode == PUT MODE) // aborted PUT operation
{ // set QEM entry to be a hole lpqeme ->txn_state = EMPTY; lpqeme- >vote = EMPTY; if ( !DelJRST_Entry ( lpqeme- >offset . segment , lpqeme- >offset . block) )
Diag ( "QS_QCommι : Problem with deleting entry from reservation table");
Sort_RST_Entrιes (lpqeme->offse . segment) ;
Fix Que Ptrs on Aborted Put (lpqeme, qeme_no) ,-
} " ~ ~ ~ else / / aborted GET operat ion
{
// reset the op f lag to a PUT lpqeme - >mode = P JMODE ; lpqeme- >txn_state = COMMIT ; lpqeme - >vote = COMMIT ;
Fιx_Que_Ptrs_on_Aborted_Get ( qeme_no) ;
58 User : root Host : bunny Class : bunny Job: stdin
///////////////////// ////////////////////// //// //////////////// ////// ///////////
/ /
// Common definitions used by OpenMQ Qservers
// ///////////////////////////////////////////////////////////////////////////// ^
// Synch objects for Queue Pointers ttdefine QEME_TS_GEN_LOCK Q/QEME_TS_Gen" #define LPG_TS_GEN_LOCK Q/LPG_TS_Gen" ttdefine QUE_HD_PTR_LOCK Q/Que_Head_Ptr" #define QUE_TL_PTR_LOCK Q/Que_Tail_Ptr" #define QEMT_LOCK Q/QEM_Table" #define MQstate_LOCK Q/MQstate" ttdefine MQops_LOCK Q/MQops" #define QSHDN_LOCK Q/QS_Shutdown" #define QSHDN_EVENT Q/QS Shutdown Even 1
// Queue server states #define QUEUE_ACTIVE OL ttdefine QUEUE SHUTDOWN IL
// Other queue server attributes ttdefine QUE_LOCK_TIMEOUT 10000 #define MAX_QSERV_THREADS 20 #define NIL -IL
#define FIFO 0L ttdefine QUEUE TEST VALUE (HANDLE) -111
// Log record attributes
#define LOG_WRITE 0L
#define MSG_WRITE IL ttdefine LRMARK -999
#define QEMTMARK -111
// Queue element size // - disk block size is the larger of // - log record or half a msg header #define QUE_FILE_SIZE 50 #define QUE_EXTENT 0.0 // queue file extent percentage #define BLOCK 46 // size of a block on disk ttdefine MSG_HDR_BLOCKS 2 // number of blocks for msg header #define MSG_BODY_BLOCKS 177 // ceil ( (8192-sizeof (MSGH) ) /BLOCK) // blocks for msg body
#define LOG_REC_BLOCKS 1 // 1 block required for log record #define MSG_HDR_SIZE 2*BLOCK // msg header size
#define MSG_BODY_SIZE 177*BLOCK // msg body size on disk #define MSG_ENTRY_BLOCKS (MSG_HDR_BLOCKS+MSGJBODYJ3LOCKS+LOGJRECJBLOCKS) #define GET LOG REC BLOCKS LOG REC BLOCKS; // log record for GETs #define TERM_LOG_REC_BLOCKS LOGJRECJBLOCKS; // ABORT/COMMOT log record
// Queue entry transactional states ttdefine INACTIVE 0L ttdefine ACTIVE IL ttdefine INITIAL 2L ttdefine PENDING 3L ttdefine PREPARED 4L ttdefine ABORT 5L ttdefine COMMIT 6L ttdefine EMPTY 7L // Queue server include files ttinclude <math.h> ttinclude <string.h>
// Queue server type defs typedef struct sgb { // Message body char tex [MAXMSGDATA] ; } MSGB, *lpMSGB; typedef struct blad { // msg block address int segment ,- // segment number int block; // block offset in segment
} BLAD, *lpBLAD; typedef struct qeme { // QEM Table entry int index; // QEM entry number ■ unsigned long timestamp; // entry creation timestamp
// needed to preserve order
MID mid; // unique msg ID short mode ,- // QGET/QPUT type short priority; // currently unused short txn_state,- // TXN state short vote ,- // participant 2PC vote int flags; // flags for TXN/NOTXN
BLAD offset; // msg block offset on disk
} QEME , 't lpQEME ; t ( edef struct ptl { // pending TXN list on disk
MID mid; // unique msg ID int qeme no // entry index in QEM Table
} PTLIST, , *lpPTLIST; typedef struct sn { // sequence number structure time_t timestamp; // timestamp based on timeO call int counter; // counter that regenerates after each restart
} SN, *lpSN; typedef struct lrclst { // list of active log records in segment int max_txns_per_seg; // max number of active txns per segment int *address,- // pointer to log record block values
} LRCLST, *lpLRCLST; typedef struct rstseg { // list msg block entry values in segment int seg_no; // segment number int *msg_block; // pointer to msg block entry values
} RSTSEG, *lpRSTSEG; typedef struct rst { // reservation table of msgs on disk int nuπjsegs; // number of segments in queue data file int msgs_per_seg; // number of msgs in the segment lpRSTSEG seg_ptr; // pointer to buffer of segment entries
} RST, *lpRST; typedef struct qe t { // QEM Table int marker; // QEM Table marker SN qem_sn; // QEM sequence number SN lrec sn; // beginning lrec timestamp in segment int num_segs,- // number of segments in datafile int max_entries; // max number of entries on queue int max_entries_limit ; // limit on max entries value int que_hd_ptr; // QEM Table head pointer int que_tl_ptr; // QEM Table tail pointer short qget_state,- // ENABLED/DISABLED switch for GETS short qput_state; // ENABLED/DISABLED switch for PUTs int num_pts; // number of pending txns
BLAD next_avail_block; // next available block byte offset lpQEME qeme_ptr,- // pointer to QEM Table entries lpRST rst_ptr, // pointer to reservation table
IpPTLIST ptl_ptr; // pointer to list of pending txns } QEMT, *lpQEMT; typedef struct opstats // RT operational statistics mt pending_gets ,- // pending gets only int pending_puts ,- // pending puts only int num_gets; // committed gets only int num_puts ; // committed puts only int num_aborts; int num_commits ;
} OPSTATS , *lpOPSTATS; typedef struct qstr { // used to record queue state short svr_state; // designate clean shutdown int nurrjrestarts ,- // number of restarts int num_recov_tries,- // number of recovery attempts time_t first_start_time; // time of fresh startup time_t last_restart_time ; // time of last restart time_t last_recov_time; // time of last recovery attempt
} QSTR, *lpQSTR; typedef struct msg { // Queue Msg Block on disk " MSGH Msg_Hdr ; // Msg Header MSGB Msg_Body; // Msg Body } QMSG, *lpQMSG; typedef struct lrec // Log Record int marker; // log record marker
SN seq no ,- // increasing sequence number short mode ; // QGET/QPUT flag short txn_state // TXN state short vote ,- // participant 2PC vote short dummy_l ; // not used at this time int flags; // Q_LOG|Q_TRAN flags int qeme no ,- // QEM Table entry number
MID mid,- // unique msg ID
BLAD offset; // msg block offset on disk
} LREC, *lpLREC; typedef struct dree // dummy structure for retrieving int field [11] ,- // records from disk at recovery } DREC, *lpDREC; typedef struct tstr
CHAR logical [NAMESIZE] ; // logical queue name
CHAR physical [NAMESIZE] ; // physical queue server name
CHAR qname[QUE_FILE_SIZE] ; // queue data file name
CHAR qstate [QUE_FILE_SIZE] ; // queue state file name
HANDLE Que File Handle; // queue datafile handle lpQHANDLE qhandle; // handle to SHM buffers IpSMBUF lpsmbuf; // pointer to SMBUF } TSTR, *lpTSTR; typedef struct mstr { // Structure for passing thread data
CHAR logical [NAMESIZE] ; // logical queue name
CHAR physical [NAMESIZE] ; // physical queue server name
CHAR qname[QUE_FILE_SIZE] ; // queue data file name
CHAR qstate [QUEJFILE_SIZE] ; // queue state file name int thr_no; // thread number
} MSTR, *lpMSTR; typedef struct tlist { // list of ops for a TID struct tlist *next,- // chain to next entry index int qeme_no ,- // entry index into QEM Table
} TLIST, *lpTLIST; typedef struct mtlist { // list of pending TIDs struct mtlist *next; // chain to next TID lpTLIST ops; // list of ops for txn
MID mid; // MID for each txn
} MTLIST, * lpMTLIST; typedef struct cntstr { int committed; int holey; } CNTSTR, *lpCNTSTR; typedef struct lpgjts { int qeme_no ; unsigned long timestamp; } LPG_TS_STR, *lpLPG_TS_STR;
// Function prototypes. void QS_QGet ( lpTSTR thr_arg) ; void QS_QPu ( lpTSTR thr_arg) ; void QS_QCommit ( lpTSTR thr_arg) ; void QSjQAdmin ( lpTSTR thr_arg) ; void QRecov (
HANDLE Que_File_Handle, int seg_no) ; void QR_ResolveJPTL (
HANDLE Que File Handle) ; void QR_Resolve_TXN_Op ( int qeme_no , short mode) ,- void QS_Resolve_TXN_Op ( int qeme_no, int *tgets, int *tputs, short mode) ; int Reconstruct_RST ( ) ;
HANDLE Create_Queue_File ( CHAR *FileName, CHAR *qstate, int Max_Elms, int Num_Segs) ,-
HANDLE Open_Queue_File ( CHAR *FileName) ;
BOOL Delete_Queue_File ( CHAR *FileName) ,- int Find_Num_Entries ( lpCNTSTR *cnt_ptr) ; int Find_QEME ( lpMID mid, int *qeme_no2, lpQEME *lpqeme2) ; int CycleJQΞME( int qeme_no, lpQEME *lpqeme2) ;
void Find_Last_Pending_Get ( int *qeme_no) ; void Fix_Que_Ptrs_on_Aborted_Put ( lpQEME lpqeme , int qeme_no) ; void Fix_Que_Ptrs_on_Aborted_Get ( int qeme_no) ; void Update_QEME_TS ( ) ; int Find_Latest_QEM (
HANDLE Que_Fi1e_Handle , lpQEMT *lpqemt2, int *seg_num) ; int Create_QEMT ( lpQEMT *lpqemt, int max_elms) ; int InitjQEMT( lpQEMT lpqem , int max_elms, int ext_elms, int num_segs) ,- int Write QEMT ( 64 HANDLE Que_File_Handle, int seg_no, lpQEMT lpqemt) ; int Retrieve_QEMT(
HANDLE Que_File_Handle, int seg_no, lpQEMT *lpqemt2) ,- int Retrieve_Msg_Hdr (
HANDLE Que_File_Handle, BLAD Msg_Addr, lpMSGH Msg_Hdr) ; int Write_Msg_Hdr (
HANDLE Que_File_Handle, BLAD Msg_Addr, lpMSGH Msg_Hdr) ; int Retrieve_Msg_Body (
HANDLE Que_File_Handle, BLAD Msg_Addr , DWORD Msg_Length, CHAR *Msg_Body) ; int Write_Msg_Body (
HANDLE Que_File_Handle, BLAD Msg_Addr , DWORD Msg_Length, CHAR *Msg_Body) ; int Retrieve__Msg (
HANDLE QueJFile_Handle, BLAD Msg_Addr , lpQMSG Msg) ; int RetrieveJLogJRec (
HANDLE Que_File_Handle, BLAD LREC_Addr, lpLREC LREC_ptr) ; int Write_LogJRec (
HANDLE Que_File_Handle, BLAD LREC_Addr, lpLREC LREC_ptr) ; void Init Active LREC ListO; int msg_entry_comp ( const void *argl, const void *arg2) ; void Sort_RST_Entries ( int seg_no) ,- int Add_RST_Entry ( int seg_no, int entry_value) ; int Del_RST_Entry ( int seg io, int entry_value) ; int Entry_in_RST ( int seg_no, int entry_value) ; int log_entry_comp ( const void *argl, const void *arg2) ,- void Sort_Log_Entries ( ) ,- int Add_LogJEntry ( int entry_value) ; int Del_Log_Entry ( int entry_value) ; int Del_Log_Entry ( int entry_value) ; int In_Log_Rec_Lis ( int start, int end, int *hit) ; int Cycle_RST_Seg( int seg_no, lpRSTSEG * lprstseg) ;
int Get_Next_BLAD (
HANDLE Que_File_Handle, int type, BLAD *offset) ,-
BOOL Check_Queue_Full ( lpQEMT lpqemt) ,-
BOOL Check_Queue_Empty ( lpQEMT lpqemt) ; void Update_Globals () ; void Conv_from_MTlist () ; void Conv toJMTlist () ; void Add_Tlis ( lpTLIST *head, int qeme_no) ,- void Add_MTlist ( lpMTLIST *head, lpMTLIST *tail, MID mid) ,-
BOOL Find_MTlis ( lpMTLIST head, lpMTLIST *pres, MID mid) ;
BOOL FindJTlist ( lpTLIST head, int qeme_no) ,- void Del_MTlist_All ( lpMTLIST *head) ,-
BOOL Del_MTlist ( lpMTLIST *head, MID mid) ; void DelJTlist ( lpTLIST *head) ; void Sub_Addr ( LONG *diff, BLAD *x, BLAD *y) ; void Conv_Addr ( LONG *diff, BLAD *x) ; int Gen_QEM_Seq_No ( IpSN tSeq_No) ; int Gen_LREC_Seq_No ( IpSN tSeq_No) ;
int Gen_QEME_TS ( unsigned long *tSeq_No) ; void test_qemt (
CHAR *filename) ; void test_lrec (
CHAR *filename) ; void test_msgh(
CHAR *filename) ; void test_msgb (
CHAR *filename) ,- void test_QS_funcs ( CHAR *logical, CHAR *physical, CHAR *qname) ,- void test_QRecov ( CHAR *qname) ; void print_QEMT ( lpQEMT lpqemt , int mode) ; void print_QEME_txn_states () ; void print_LREC( lpLREC lplrec) ; void print_SMBUF (
IpSMBUF lpsmbuf) ; void print_MSGH ( lpMSGH lpmsgh) ; void print_MSGB (
CHAR *lpmsgb) ,- void print_RST ( ) ; void print_Active_Log_List () ,- void print_PTList () ; void print_QAdm_Stats () ;
BOOL Bigger_Seq_No ( IpSN seq_nol, IpSN seq_no2) ;
* Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
* UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
* LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
* IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
* OR DISCLOSURE.
*
THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
* OpenMQ
Module: qsget.c Author: David Wong 9/8/95
*/
// Include Files ttinclude "qlib.h" ttinclude "qserv. h" ttinclude "qadmin.h"
extern lpQEMT MQEMT; extern lpQSTR MQstate; extern lpOPSTATS MQops; extern lpMTLIST PendingJTXNs ; extern int BLOCKS_PER_SEG; extern int SEGMENT_SIZE; extern int TOT_MSG_BLOCKS ; extern int QEMT_Size; extern int QEMT_Seq_No ,- extern int LREC_Seq_No ; extern int NUM_SEGS; extern int MAX_ELMS; extern unsigned long QEMEJTS; extern lpLPG_TS_STR Last_Pending_Ge j
void QS_QGet ( lpTSTR thr_arg)
{
HANDLE QueJFileJHandle;
HANDLE hQHD, hQTL, hLPG;
HANDLE hQEMT, hMQops ;
BOOL Return_Status; lpMTLIST ThisJTXN;
IpSMBUF lpsmbuf; lpQEME lpqeme ;
LREC log_rec;
BLAD tblad; int status; int qeme_no ; int new_hd_ptr; int no_new_hd=0; int done=0 ; _ „ int found=0; θ9 lpsmbuf = ( SMBUF * ) malloc ( sizeof (SMBUF) ) ; Que_File_Handle = thr_arg- >Que_FileJHandle ;
// Check if GETs are disabled . if (MQEMT- >qget state == DISABLED)
{
Diag ("GET Operations for DiskQ(%s) is DISABLED" , thr_arg- >qname) ; if (thr_arg->qhandle != QUEUE_TEST_VALUE)
QreplyAfterListen (thr_arg- >qhandle , ACK_MODE , SUB_MODE_DISABLED ,0,0,0) ; return; }
// Obtain locks on queue pointers.
// Protocol is to obtain hQHD first,
// then hQTL. hQHD = OpenMutex (SYNCHRONIZE, FALSE, QUE_HD_PTR_LOCK) ,- if OhQHD)
Diag ( "QS_QGet : Can't OpenMutex for queue head pointer lock"),- if ((status = WaitForSingleObject (hQHD, QUE_LOCK_TIMEOUT) ) != WAIT_OBJECTJO) Diag ( "QSjQGet : Synch wait for queue head pointer lock failed"); hQTL = OpenMutex (SYNCHRONIZE, FALSE, QUEJTL_PTR_LOCK) ; if (IhQTL)
Diag ( "QS_QGet : Can't OpenMutex for queue tail pointer lock"); if ((status = WaitForSingleObject (hQTL, QUE_LOCK_TIMEOUT) ) !=
WAITJOBJECT_0) Diag ( "QS_QGe : Synch wait for queue tail pointer lock failed");
// Check if queue is EMPTY if (Check Queue Empty (MQEMT) == TRUE)
{
Diag ( "DiskQ (%s) : EMPTY" , thr_arg->qname) ,- if (thr_arg->qhandle != QUEUE_TEST_VALUE)
QreplyAfterListen (thr_arg- >qhandle, ACK_MODE , SUB_MODE_EMPTY, 0,0,0) ,- ReleaseMutex (hQHD) ; ReleaseMutex (hQTL) ; return;
}
qeme_no = MQEMT- >que_hd_ptr ,- status = Cycle QEME (qeme_no, &lpqeme) ; if (MQEMT- >que hd ptr == MQEMT- >que_tl_ptr)
{ ~ " if ( (lpqeme->mode == PUT_MODE) && (lpqeme->txn state == COMMIT))
{
MQEMT- >que_hd_ptr = NIL ; MQEMT- >que_tl_ptr = NIL ; if ( lpqeme - >txn state == EMPTY)
{ MQEMT- >que_hd_ptr = NIL ;
MQEMT- >que tl ptr = NIL ;
} ~ ~
Diag ( "DiskQ (%s) : EMPTY" , thr_arg->qname) ,- if (thr_arg->qhandle != QUEUE_TEST_VALUE)
QreplyAfterListen (thr_arg->qhandle, ACK_MODE,
SUB_MODE_EMPTY, 0,0,0) ; ReleaseMutex (hQTL) ,- ReleaseMutex (hQHD) ,- return;
, ' else // head != tail
{ new_hd_ptr = MQEMT- >que_hd_ptr ,- if ( (lpqeme->mode == PUT_MODE) && (lpqeme->txn state == COMMIT))
{ MQEMT->que hd ptr = (MQEMT->que hd ptr+1) %MQEMT- >max entries,
} else
{ // head entry is not yet committed; // find next one that is committed. while (Idone && ! found)
{ if ( (lpqeme->mode == PUT_MODE) && ( lpqeme- >txn_state == COMMIT))
{ done = 1 ; found = 1 ,-
} else
{ if ( (lpqeme->mode == PUT_MODE) &&
( lpqeme- >txn_state == PENDING) &&
( !no new hd) )
{ " ~ new_hd_ptr = qeme_no; no new hd = 1 ;
} ~ ~ if (qeme_no == MQEMT- >que_tl_ptr) done = 1 ,- else
{ qeme_no = (qeme_no+l) %MQEMT->max_entries; status = Cycle QEME (qeme no, klpqeme) ; }
if (found) ^. if ( (qeme_no == MQEMT- >que_tl_ptr) && ( ! no_new_hd) )
MQEMT- >quejhd_ptr = NIL; MQEMT- >que tl ptr = NIL;
} else MQEMT- >que hd ptr = new hd ptr;
} else
{ Diag ( "DiskQ (%s) : EMPTY" , thr_arg->qname) ,- if (thr_arg->qhandle != QUEUEJTESTJVALUE)
QreplyAfterListen ( hr_arg- >qhandle , ACK_MODE , SUB_MODE_EMPTY, 0,0,0) ; ReleaseMutex (hQTL) ,- ReleaseMutex (hQHD) ,- return;
// Change state of QEM entry before // releasing queue pointer locks, lpqeme- >txn_state = ACTIVE; lpqeme- >vote = INITIAL;
ReleaseMutex (hQTL) ; ReleaseMutex (hQHD) ; status = Retrieve_Msg_Hdr (Que_File_Handle, lpqeme ->offset , Sclpsmbuf->msgh) ,- lpqeme- >mid. host = thr_arg->lpsmbuf ->msgh. mid. host , lpqeme->mid. tid = thr_arg->lpsmbuf ->msgh.mid . tid; lpqeme- >mid .uid = thr_arg->lpsmbuf->msgh.mid.uid; lpqeme->mode = GET_M0DE; lpqeme- >flags = thr_arg->lpsmbuf ->msgh. flags ,- lpqeme->priority = FIFO; tblad. segment = lpqeme- >offset . segmen ; tblad. block = lpqeme->offset .block+MSG_HDR_BLOCKS; status = Retrieve_Msg_Body(Que_File_Handle, tblad, lpsmbuf ->msgh. size, lpsmbuf ->mdata) ,-
// Diag ( "DiskQ (%s) : DEQUEs message - %s" , thr_arg->qname, lpsmbuf ->mdata) ; DiagC'DiskQ (%s) : DEQUES message" , thr_arg->qname) ,-
// increment get ops counter hMQops = OpenMutex (SYNCHRONIZE, FALSE, MQops_LOCK) ; if (! hMQops)
Diag("QS_QGe : Can't OpenMutex for MQops stats lock"); if ((status = WaitForSingleObject (hMQops, QUEJLOCKJTIMEOUT) )
WAITJDBJECTJO) DiagC'QSJQGet : Synch wait for MQops stats lock failed"),- MQops - >num_gets++ ,- hQEMT = OpenMutex ( SYNCHRONI ZE , FALSE , QEMT_LOCK) ; if (! hQEMT)
Diag ("QS_QGe : Can't OpenMutex for QEM Table lock"),- if ((status = WaitForSingleObjec (hQEMT, QUE_LOCK_TIMEOUT) ) ! =
WAIT_OBJECTJO) Diag("QS_QGet : Synch wait for QEM Table lock failed");
// if transactional, then write PREPARED log record if (BITSET(Q TRAN, thr arg- >lpsmbuf- >msgh . flags) )
{ log_rec .marker = LRMARK; status = Gen_LREC_SeqJNo (&log_rec. seq_no) ; log_rec.mode = GET_MODE; log_rec . flags = thr_arg->lpsmbuf ->msgh. flags ,- log_rec . txn_state = PENDING; log_rec.vote = PREPARED; log_rec .qeme_no = qeme_no; log_rec .mid. host = thr_arg- >lpsmbuf->msgh. mid . host , log_rec .mid. tid = thr_arg- >lpsmbuf ->msgh. mid. id, log_rec .mid.uid = thr_arg->lpsmbuf->msgh.mid.uid; log_rec . offset . segment = lpqeme- >offset . segment ;; log_rec .offset .block = lpqeme->offset .block ,-
// Fetch next available on-disk slot for log write. if (!Get Next BLAD(Que File Handle, LOG WRITE, ktblad) )
{ ~ "
// queue data file is full or too fragmented.
Diag ( "DiskQ (%s) is either full or too fragmented . " , thr_arg->qname) ; if (thr_arg->qhandle != QUEUE_TEST_VALUE)
QreplyAfterListen ( thr_arg- >qhandle , ACK_MODE ,
SUB_MODE_FULL, 0,0,0) ;
ReleaseMutex (hQEMT) ;
ReleaseMutex (hMQops) ,- return; } status = Write_Log_Rec (Que_File_Handle, blad, &log_rec) ;
// return msg queue data and ACK msg to client if (thr_arg->qhandle != QUEUEJTESTJVALUE)
QreplyAfterListen ( thr_arg- >qhandle , ACK_MODE , SUB_MODE_OK, lpsmbuf ->mdata, lpsmbuf ->msgh. size, klpsmbuf ->msgh) ,-
// update QEM entry lpqeme ->mode = GET_MODE; lpqeme->txn_state = PENDING; lpqeme->vote = PREPARED;
// add txn and/or op to pending txn list
Return_Status = Find_MTlist (PendingJTXNs , &This_TXN, lpqeme->mid) ,- if (Return_Status == FALSE)
Add_MTlist (&Pending_TXNs, &This_TXN, lpqeme- >mid) ,- AddJTlist ( &ThisJTXN- >ops , qeme_no) ,-
MQops - >pending_gets++ ;
// update last pending GET timestamp hLPG = OpenMutex ( SYNCHRONIZE , FALSE , LPG_TS_GEN_LOCK) ; if (IhLPG)
Diag("QS_QGet: Can't OpenMutex for LPGJTSJGEN Lock"); if ((status = WaitForSingleObjec (hLPG, QUEJLOCKJTIMEOUT) ) !=
WAIT_OBJECTJO) Diag("QS_QGet: Synch wait for LPG_TS_GEN Lock failed"); if (lpqeme->timestamp > Last Pending_Get->timestamp)
{ Last_Pending_Get->qeme_no = qeme_no;
Last Pending Get->timestamp = lpqeme->timestamp; }
ReleaseMutex (hLPG) ,-
} else
{ // return msg queue data and ACK msg to client if (thr_arg->qhandle != QUEUE_TEST_VALUE)
QreplyAfterListen (thr_arg->qhandle,ACK_MODE,SUB_MODE_OK, lpsmbuf ->mdata, lpsmbuf ->msgh. size, -clpsmbuf - >msgh) ,-
// update QEM entry lpqeme- >mode = GET_MODE; lpqeme ->txn_state = EMPTY; lpqeme- >vote = EMPTY;
// increment commit counter MQops->num_commits++ ;
// delete on-disk entry slot from reservation table if ( !Del_RST_Entry (lpqeme->offset . segment, lpqeme- >offset .block) )
Diag ( "QS_QGet : Problem with deleting entry from reservation table"); else Sort RST Entries (lpqeme- >offset . segment) ,-
} ~ "
ReleaseMutex (hMQops) ; ReleaseMutex (hQEMT) ,- free (lpsmbuf) ;
Diag ("TID = %d, UID = %d, index= %d, offset . segment = %d, offset. block = %d", lpqeme->mid. tid, lpqeme- >mid .uid, lpqeme- >index, lpqeme- >offset .segment, lpqeme->offset .block) ;
} /*
* Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
* UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
* LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
* IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
* OR DISCLOSURE. *
* THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
* TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
* OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA. *
* OpenMQ
* Module: qsput . c
* Author: David Wong 9/8/95
/
// Include Files ttinclude "qlib.h" ttinclude "qserv. h" ttinclude "qadmin.h"
extern lpQEMT MQEMT; extern lpQSTR MQstate; extern lpOPSTATS MQops; extern lpMTLIST PendingJTXNs ; extern int BLOCKS_PER_SEG; extern int SEGMENT_SIZE; extern int TOT_MSG_BLOCKS ; extern int QEMT_Size,- extern int QEMT_SeqJNo ; extern int LREC_Seq_No ; extern int NUM_SEGS; extern int MAXJΞLMS; extern unsigned long QEMEJTS; extern lpLPG_TS_STR Last_Pending_Ge ; extern lpLRCLST Active_LREC_List ,-
//
// Issue - create separate lock for obtaining
// space in reservation table.
//
void QS_QPut ( lpTSTR thr_arg)
HANDLE Que_File_Handle;
HANDLE hQHD, hQTL;
HANDLE hQEME , hQEMT , hMQops ;
BOOL Return_Status; lpMTLIST ThisJTXN;
IpSMBUF lpsmbuf; lpQEME lpqeme ;
LREC log_rec;
BLAD temp_offset ; int status,- int qeme no ; int qeme no2 ,- int done=0 ,- int found=0 ;
lpsmbuf = thr_arg- >lpsmbuf ; Que_File_Handle = thr_arg- >Que_File_Handle ;
// Check if PUTs are disabled . if (MQEMT- >qput state == DISABLED)
{
Diag ("PUT Operations for DiskQ(%s) is DISABLED" , hr_arg->qname) if (thr_arg->qhandle != QUEUE_TEST_VALUE)
QreplyAf erListen (thr_arg->qhandle,ACK_MODE,
SUB_MODE_DISABLED ,0,0,0) ; return; }
// Obtain locks on queue pointers.
// Protocol is to obtain hQHD first,
// then hQTL. hQHD = OpenMutex (SYNCHRONIZE, FALSE, QUE_HD_PTR_LOCK) ; if (IhQHD)
Diag ( "QSJQPUT: Can't OpenMutex for queue head pointer lock"); if ((status = WaitForSingleObject (hQHD, QUE_LOCK_TIMEOUT) ) !=
WAITJDBJECTJO) Diag ( "QS_QPut : Synch wait for queue head pointer lock failed"); hQTL = OpenMutex (SYNCHRONIZE, FALSE, QUE_TL_PTR_LOCK) ; if (IhQTL)
Diag("QS_QPUT: Can't OpenMutex for queue tail pointer lock"); if ((status = WaitForSingleObject (hQTL, QUE_LOCK_TIMEOUT) ) !=
WAITJDBJECTJO ) Diag ( "QS_QPut : Synch wait for queue tail pointer lock failed");
if (Check Queue Full (MQEMT) == TRUE)
{
Diag("DiskQ(%s) is FULL" , thr_arg->qname) ; if (thr_arg->qhandle != QUEUE_TEST_VALUE)
QreplyAfterListen ( hr_arg- >qhandle , ACK_MODE ,
SUB_MODE_FULL,0,0,0) ; ReleaseMutex (hQTL) ,- ReleaseMutex (hQHD) ; return;
// Obtain lock on QEMT to fetch next available // entry in reservation table and disk writes. hQEMT = OpenMutex (SYNCHRONIZE, FALSE, QEMT_LOCK) ; if (! hQEMT)
Diag("QS_QPUT: Can't OpenMutex for QEM Table lock"); if ((status = WaitForSingleObject (hQEMT, QUE_LOCK_TIMEOUT) ) !=
WAITJOBJECTJO) Diag("QS_QPut : Synch wait for QEM Table lock failed"),-
if (MQEMT- >que hd ptr == NIL)
{ hMQops = OpenMutex ( SYNCHRONIZE , FALSE , MQops_LOCK) ; if ( ! hMQops )
Diag("QS_QCommit : Can't OpenMutex for MQops stats lock"); if ((status = WaitForSingleObjec (hMQops, QUE_LOCKJTIMEOUT) ) !=
WAITJDBJECTJO) Diag("QS_QCommit : Synch wait for MQops stats lock failed");
if (MQops ->pending gets == 0)
{ // Fetch next available on-disk slot for msg. if (!Get Next BLAD (Que File Handle, MSG WRITE, &temp offset))
{ ~ " // queue data file is full or too fragmented.
Diag ( "DiskQ (%s) is too fragmented - PUT failed. ", thr_arg->qname) ; if (thr_arg->qhandle != QUEUE_TEST_VALUE)
QreplyAfterListen (thr_arg->qhandle,ACK_MODE,SUB_MODE_FULL, 0,0,0) ; ReleaseMutex (hQEMT) ; ReleaseMutex (hQTL) ; ReleaseMutex (hQHD) ; return,- }
MQEMT- >que_hd_ptr = 0; MQEMT- >que_tl_ptr = 0; status = Cycle QEME (MQEMT- >que tl ptr , klpqeme) ;
} else
{ qeme_no = Las _Pending_Get->qeme_no,- if (qeme no == NIL)
{
Diag ( "DiskQ (%s) has faulty RT counters" , thr_arg->qname) ,- if (thr_arg->qhandle != QUEUEJTESTJVALUE)
QreplyAfterListen (thr_arg- >qhandle , CK_MODE, SUB_MODE_FULL,0,0,0) ;
ReleaseMutex (hMQops) ;
ReleaseMutex (hQTL) ,-
ReleaseMutex (hQHD) ; return; } qeme_no2 = qeme_no ,- qeme_no = (qeme_no+l) %MQEMT->max_entries; status = Cycle_QEME (qeme_no, Sdpqeme) ; while (!done && ! found) { if (lpqeme->txn state == EMPTY)
{ done = 1 ,- found = 1 ,-
} else
{ qeme_no = (qeme_no+l) %MQEMT->max_entries; if (qeme_no == qeme_no2) done = 1 ,- else status = Cycle_QEME (qeme_no, &lpqeme) ;
if (found)
{ // Fetch next available on-disk slot for msg. if (!Get Next BLAD(Que File Handle, MSG WRITE, ktemp offset)) { - - - - . -
// queue data file is full or too fragmented.
Diag ( "DiskQ (%s) is too fragmented - PUT failed .", thr_arg- >qname) ; if (thr_arg->qhandle != QUEUEJTESTJVALUE)
QreplyAf erListen (thr_arg->qhandle, ACK_MODE, SUB_MODEJFUL , 0,0,0) ReleaseMutex (hQEMT) ,- ReleaseMutex (hQTL) ; ReleaseMutex (hQHD) ; return; }
MQEMT- >que_hd_ptr = qeme_no ; MQEMT- >que_tl_ptr = qeme_no; else
{
Diag ( "DiskQ (%s) has faulty que pointers" , thr_arg- >qname) ,- if (thr_arg->qhandle != QUEUE_TEST_VALUE)
QreplyAfterListen ( hr_arg- >qhandle , ACK_MODE, SUB_MODE_FULL,0,0,0) ; ReleaseMutex (hMQops) ,- ReleaseMutex (hQTL) ; ReleaseMutex (hQHD) ; return;
> >
ReleaseMutex (hMQops) ;
} else
{ if{ (!Get_Next_BLAD(Que_File_Handle, MSG WRITE, &temp_offset ) )
// queue data file is full or too fragmented.
Diag( "DiskQ(%ε) is too fragmented - PUT failed. ", thr_arg->qname) ,- if (thr_arg->qhandle != QUEUE_TEST_VALUE)
QreplyAfterListen (thr_arg->qhandle,ACK_MODE,SUB_MODE_FULL, 0, 0,0); ReleaseMutex (hQEMT) ; ReleaseMutex (hQTL) ; ReleaseMutex (hQHD) ; return;
} // This case is true only iff que head is EMPTY. // Roll over both que head and tail pointers. if (( (MQEMT- >que_tl_ptr+l) %MQEMT->max_entries) == MQEMT- >que_hd_ptr) MQEMT- >que_hd_ptr = (MQEMT- >que_hd_ptr+l ) %MQEMT- >max_entries ,•
MQEMT- >que_tl_ptr = (MQEMT- >que_tl_ptr+l ) %MQEMT->max_entries ,- status = Cycle QEME (MQEMT- >que tl ptr , klpqeme) ;
} " ~
// Change state of QEM entry before // releasing queue pointer locks. lpqeme->txn_state = ACTIVE; lpqeme->vote = INITIAL;
ReleaseMutex (hQTL) ; ReleaseMutex (hQHD) ;
// Now assign storage location to QEM entry. lpqeme- >offset . segment = temp_offset . segment , lpqeme- >offset . block = temp_offset .block,
// Fetch QEM entry timestamp generator lock. hQEME = OpenMute (SYNCHRONIZE, FALSE, QEMEJTSJGENJLOCK) ; if (! hQEME)
Diag ( "QS_QPUT : Can ' t OpenMutex for QEMEJTS Lock " ) ; if ( ( status = WaitForSingleObj ect (hQEME , QUE_LOCK_TIMEOUT) ) ! =
WAITJDB JECTJO )
Diag C'QSJQPut : Synch wait for QEMEJTS Lock f ailed" ) ; status = GenjQEMEJTS ( &lpqeme- >timestamp) ;
ReleaseMutex (hQEME) ; lpqeme->mid. host = lpsmbuf ->msgh.mid. host ; lpqeme->mid. tid = lpsmbuf ->msgh. mid. tid, lpqeme ->mid. uid = lpsmbuf->msgh. mid. uid; lpqeme->mode = PUT_MODE; lpqeme->flags = lpsmbuf->msgh. flags ; lpqeme- >priority = FIFO;
// NoWait case on disk write of msg
// send ACK msg to client immediately if ( ( !BITSET(Q_TRAN, lpsmbuf- >msgh . flags) )
&& (!BITSET(Q LOG, lpsmbuf ->msgh.flags) ) )
{ if (thr_arg->qhandle != QUEUE_TEST_VALUE)
QreplyAfterListen (thr arg->qhandle, ACK MODE, SUB MODE OK, 0,0,0); } status = Write_Msg_Hdr (Que_File_Handle, lpqeme- >offset, &lpsmbuf->msgh) ; temp_offset . segment = lpqeme ->offset .segmen ;; temp_offset. block = lpqeme->offset .block* (MSG_HDR_BLOCKS) ,- status = Write_Msg_Body (Que_File_Handle, temp_offset, lpsmbuf ->msgh. size, lpsmbuf ->mdata) ;
// Diag ( "DiskQ (%s) : ENQUEs message - %s" , thr_arg->qname, lpsmbuf ->mdata) ; Diag( "DiskQ (%s) : ENQUEs messages ", thr_arg- >qname) ,-
// increment put ops counter hMQops = OpenMutex (SYNCHRONIZE, FALSE, MQops_LOCK) ; if (! hMQops)
Diag("QS_QPUT: Can't OpenMutex for MQops stats lock"); if ((status = WaitForSingleObject (hMQops, QUE_LOCK_TIMEOUT) ) !=
WAITJOBJECTJO) DiagC'QSjQPut : Synch wait for MQops stats lock failed");
MQops->num_puts++;
// if transactional, then write log record if (BITSET(Q TRAN, lpsmbuf ->msgh. flags) )
{ log_rec .marker = LRMARK; status = Gen_LREC_Seq_No (&log_rec . seq_no) ; log_rec.mode = PUT_MODE; log_rec . flags = lpsmbuf ->msgh. flags ; log_rec . txn_state = PENDING; log_rεc.vote = PREPARED; log_rec . qeme_no = MQEMT- >que_tl_ptr ; log_rec .mid. host = lpqeme->mid. host ; log_rec .mid. tid = lpqeme->mid. tid; log_rec .mid .uid = lpqeme- >mid. uid; log_rec .offset .segment = lpqeme->offset . segment , log_rec .offset .block = lpqeme->offset . block; temp_offset .segment = lpqeme- >offset . segmen ; temp_offset .block = lpqeme->offse .block +
(MSG_HDR_BLOCKS+MSG_BODY_BLOCKS) ; status = Write_Log_Rec (Que_File_Handle, temp_offset, &log_rec) ;
// send ACK msg back to client if (thr_arg->qhandle != QUEUE_TEST_VALUE)
QreplyAfterListen(thr_arg->qhandle,ACK_MODE, SUB_MODE_OK, 0, 0, 0) ,-
// update QEM entry lpqeme- >txn_state = PENDING; lpqeme->vote = PREPARED;
// add txn and/or op to pending txn list
Return_Status = Find_MTlist ( PendingJTXNs , &This_TXN, lpsmbuf ->msgh. mid) ; if (Return_Status == FALSE)
Add_MTlist (&Pending_TXNs, &This_TXN, lpsmbuf->msgh. mid) ,- AddJTlist ( -ThisJTXN- >ops , QEMT- >que_tl_ptr) ; MQops - >pending_puts++ ,
ReleaseMutex ( hQEMT) ,-
} else
{ ReleaseMutex (hQEMT) ,-
// send ACK msg back to client if Q_LOG flag if ( (BITSET(Q_LOG, lpsmbuf->msgh. flags) == Q_LOG) && (thr_arg->qhandle != QUEUEJTESTJVALUE) ) QreplyAfterListen (thr_arg->qhandle,ACK_MODE,SUB_MODE_OK, 0,0,0) ,-
// update QEM entry lpqeme->txn_state = COMMIT lpqeme->vote = COMMIT;
// increment commit counter MQops ->num commits++; }
ReleaseMutex (hMQops) ;
Diag ("TID = %d, UID = %d, index = %d, offset . segment = %d, offset. block = %d", lpqeme- >mid .tid, lpqeme->mid .uid, lpqeme->index, lpqeme->offset . segment , lpqeme- >offset .block) ,- }
/*
Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED. UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION OR DISCLOSURE.
THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
OpenMQ
* Module : qtest . c * Author : David Wong 9/8/95
*/
// Include Files ttinclude "qlib.h" ttinclude "qserv. h" ttinclude "qadmin.h"
extern lpQEMT MQEMT; extern lpQSTR MQstate; extern lpMTLIST PendingJTXNs ,- extern int BLOCKS_PER_SEG ; extern int SEGMENT_SIZE; extern int TOT_MSG_BLOCKS ; extern int QEMT_Size; extern int QEMT_Seq_No; extern int LREC_Seq_Nθ; extern int NUM_SEGS ; extern int MAX_ELMS ; extern unsigned long QEMEJTS; extern lpLRCLST Active LREC List;
void test_qemt ( CHAR *filename)
{
HANDLE QueJFile_Handle;
HANDLE hQHD, hQTL, hQEMT;
BOOL Return_Status ,- lpQEMT lpqemt , lpqemt2 ; lpQEME lpqeme ; int i, status; status = CreatejQEMT(&lpqemt,MAX_ELMS) ,- status = Init_QEMT( lpqemt, MAX_ELMS,0,NUM_SEGS) ; hQHD = CreateMutex (NULL, // No security
TRUE, // Get ownership of mutex QUE HD PTR LOCK) ; // Name if (IhQHD)
Diag ("CreateMutex for Que Head Pointer lock failed.") hQTL = CreateMutex (NULL , // No security
TRUE , // Get ownership of mutex
QUE_TL_PTR_LOCK) ; // Name if (IhQTL)
Diag ( "CreateMutex for Que Head Pointer lock failed."); hQEMT = CreateMutex (NULL, // No security
TRUE, // Get ownership of mutex
QUE_TL_PTR_LOCK) ; // Name if (! hQEMT)
Diag ( "CreateMutex for Que Head Pointer lock failed."),- lpqeme = lpqemt ->qeme_ptr; for(i=l; i<=10; i++)
{ lpqeme->mid. host = 11111; lpqeme->mid. tid = 22222; lpqeme->mode = PUT_MODE; lpqeme- >flags = 0 ,- lpqeme- >priority = 0; lpqeme- >txn_state = ACTIVE; lpqeme- >vote = INACTIVE; lpqeme- >offset . segment = 44444; lpqeme->offset .block = 55550+i; lpqeme++,- }
Que_File_Handle = Open_Queue_File (filename) ; if (Que_File_Handle == INVALIDJHANDLEJVALUE) Diag ( "-Problem opening queue file ..."); status = Gen_QEM_Seq_No (&MQEMT->qem_sn) ,- status = Write_QEMT(Que_File_Handle, 0, lpqemt) ; if (status == QFAIL)
Diag ("QEMT Write Failed ..."); status = Create_QEMT(&lpqemt2,MAX_ELMS) ; status = Retrieve_QEMT(Que_File_Handle, 1, &lpqemt2) ,- if (status == QFAIL)
Diag ("QEMT Read Failed ...");
Return_Status = CloseHandle (Que_File_Handle) ,- if (Return_Status == FALSE)
DiagC'Could not close queue file handle"); printJQEMT( lpqemt2, 1) ;
void test_lrec ( CHAR *filename) HANDLE Que_File_Handle;
BOOL Return_Status ; lpLREC lplrec ,- lpLREC lplrec2 ;
BLAD LREC_Addr ; int status;
Que_File_Handle = Open_Queue_File (filename) ;
LREC_Addr . segment = 1 ,- LREC_Addr. block = 1 ; lplrec = (LREC *) malloc (sizeof (LREC) ) ; lplrec- >marker = LRMARK; status = Gen_LREC_Seq_No (&.lplrec->seq_no) ; lplrec->mode = PUT_MODE; lplrec->qeme_no = 999; lplrec ->txn_state = ACTIVE; lplrec ->vote = INACTIVE; lplrec- >mid. host = 11111; lplrec->mid. id = 22222; lplrec- >offset . segment = 1 ; lplrec->offset .block = 1 ,- print_LREC (lplrec) ,- status = WriteJLogJRec (Que_File_Handle, LREC_Addr, lplrec) ; if (status == QFAIL)
DiagC'Log Write Failure ... " ) ; lplrec2 = (LREC *) malloc (sizeof (LREC) ) ; status = Retrieve_Log_Rec (Que_File_Handle, LREC_Addr, lplrec2) if (status == QFAIL)
DiagC'Log Read Failure ... " ) ; print_LREC(lplrec2) ;
Return_Status = CloseHandle (Que_File_Handle) ,- if (Return_Status == FALSE)
DiagC'Could not close queue file handle");
void test msgh (
CHAR *filena e)
{
HANDLE Que_File_Handle ;
BOOL Return_Status ,- lpMSGH lpmsgh ; lpMSGH lpmsgh2 ;
BLAD MSGH_Addr; int status;
QueJFile_Handle = OpenJQueueJFile (filename) MSGH_Addr . segment = 1; MSGH_Addr. block = 1 ,- lpmsgh = (MSGH *) malloc (sizeof (MSGH) ) ; lpmsgh->type_coding = 999999; lpmsgh- >mode = 1; lpmsgh- >sub_mode = 2 ; lpmsgh- >flags = QJTRAN; lpmsgh- >mid. host = 11111; lpmsgh- >mid. tid = 22222; lpmsgh- >time = 33333; lpmsgh- >to_node = 12345; lpmsgh- >to_port = 23456; lpmsgh- >to_smbuf = 44444; strcpyt lpmsgh- >to_server„ "Que_ServerJl" ) ,- strcpy (lpmsgh- >to_logical, "Que_Service_l" ) ,- lpmsgh- from_smbuf = 45677; lpmsgh- >reply_smbuf = 34567; lpmsgh- >size = 888;
print_MSGH ( lpmsgh) ,- status = Write_Msg_Hdr (Que_File_Handle,MSGH_Addr, lpmsgh) ,- if (status == QFAIL)
Diag ("Msg Header Write Failure ... "); lpmsgh2 = (MSGH *) malloc (sizeof (MSGH) ) ;
status = Retrieve_Msg_Hdr (Que_File_Handle, MSGHjAddr , lpmsgh2) if (status == QFAIL)
Diag ("Msg Header Read Failure ... "),- print_MSGH (lpmsgh2) ;
Return_Status = CloseHandle (Que_FileJHandle) ; if (Return_Status == FALSE)
DiagC'Could not close queue file handle");
void test_msgb ( CHAR *filename)
{
HANDLE Que_File_Handle;
BOOL Return_Status;
BLAD MSGB_Addr ;
CHAR stringl[41] ;
CHAR string2 [41] ; int status;
Que_File_Handle = Open_Queue_File (filename) ; MSGB_Addr . segment = 1 ; MSGB_Addr . block = 1 ; strcpy (stringl, "The quick brown fox jumps over the fence."); print_MSGB (stringl) ; status = WriteJMsgJBody (QueJFileJHandle, MSGB_Addr, 1, stringl) ; if (status == QFAIL)
Diag ("Msg Body Write Failure ... " ) ,- status = Retrieve_Msg_Body (Que_File_Handle,MSGB_Addr, 41, string2) ,- if (status == QFAIL)
Diag ("Msg Body Read Failure ... " ) ; print_MSGB(string2) ;
Return_Status = CloseHandle (Que_File_Handle) ,- if (Return_Status == FALSE)
Diag("Could not close queue file handle"),-
void test_QS_funcs ( CHAR *logical, CHAR *physical, CHAR *qname)
(
IpSMBUF lpsmbuf; lpTSTR thr_arg; lpsmbuf = (SMBUF *) malloc (sizeof (SMBUF) ) ; strcpy (lpsmbuf ->mdata, "This is a very small message"),- strcpy (lpsmbuf->name, "Tem_Buffer_l") ; lpsmbuf ->status = 0 ,- lpsmbuf->sub_status = 0; lpsmbuf- >msgh . type_coding = 1; lpsmbuf->msgh. mode = PUT_MODE; lpsmbuf ->msgh. sub_mode = 0; // lpsmbuf->msgh. flags = QJTRAN; lpsmbuf->msgh. ime = 33333; lpsmbuf->msgh. to_node = 1234567 lpsmbuf - >msgh . tojport = 2345678 lpsmbuf - >msgh . to_smbuf = 2345678 strcpy (lpsmbuf->msgh.to_server, "barny") ; strcpy (lpsmbuf ->msgh.to_logical, "barny/Ql") ; lpsmbuf->msgh. from_smbuf = 4567890; lpsmbuf- >msgh . reply_smbuf. = 3456789; lpsmbuf->msgh. size = strlen (lpsmbuf->mdata) ; thr_arg = (TSTR *) malloc (sizeof (TSTR) ) ; strcpy (thr_arg->logical, logical) ; strcpy (thr_arg->physical, physical) ; strcpy (thr_arg->qname,qname) ; thr_arg->qhandle = QUEUEJTEST_VALUE ; thr_arg->lpsmbuf = lpsmbuf; lpsmbuf->msgh. flags Q_LOG; lpsmbuf - >msgh . mid . host 33333; lpsmbuf- >msgh.mid. tid 1; QS_QPut (thr_arg) ; lpsmbuf- >msgh . mode ADM NREQ_MODE; lpsmbuf- >msgh . sub_mode QADM REQ STATS; QS QAdmin(thr_arg) ; lpsmbuf - >msgh . flags Q_TRA ; lpsmbuf - >msgh . mid . host 214; lpsmbuf- >msgh . mid . id 2; QS_QPut (thr_arg) ,- lpsmbuf ->msgh. flags QJTRAN; lpsmbuf - >msgh . mid . host 214; lpsmbuf->msgh. mid. tid 2; QSjQGet (thr_arg) ; lpsmbuf - >msgh . mode ADMINREQ_MODE ; lpsmbuf- >msgh . sub_mode QADM REQ STATS; QS_QAdmin(thr_arg) ; lpsmbuf - >msgh . mode ABORT_MODE ; lpsmbuf - >msgh . mid . host 214; lpsmbuf->msgh.mid . tid 2; QS_QCommit (thr_arg) ; lpsmbuf - >msgh . mode ADMINREQ_MODE ; lpsmbuf- >msgh. sub_mode QADM REQ STATS; QS_QAdmin(thr arg) ;
lpsmbuf- >msgh . mid . host 216; lpsmbuf->msgh. mid. id 3; QS_QPut (thr_arg) ; lpsmbuf- >msgh . mid . host 217; lpsmbuf->msgh. mid. tid 4; QS_QPut (thr_arg) ,- printJQEMT (MQEMT, 1) ; lpsmbuf- >msgh .mid . host 218; lpsmbuf - >msgh . mid . id 5; QS_QPut (thr_arg) ; lpsmbuf- >msgh. mid. host 219; lpsmbuf- >msgh.mid . tid 6; QS_QPut (thr arg) ; lpsmbuf - >msgh . mid . host 219; lpsmbuf - >msgh . mid . tid 6; QSJQPut ( thr_arg) ,- lpsmbuf - >msgh . mid . host 12345; lpsmbuf - >msgh . mid . tid 678; QS_QPut ( thr_arg) ; lpsmbuf - >msgh . mid . host 12345; lpsmbuf - >msgh . mid . tid 678; QS_QPut ( thr_arg) ; print_QEMT (MQEMT , 1 ) ; lpsmbuf- >msgh . mode COMMIT _MODE ; lpsmbuf- >msgh. mid . host 214; lpsmbuf- >msgh . mid . tid 2; QS_QCommit (thr_arg) ; lpsmbuf->msgh. mid. host 33333; lpsmbuf ->msgh. mid. tid ill; QS_QGet (thr_arg) ; print_PTList () ,- lpsmbuf - >msgh . mode COMMIT _MODE ; lpsmbuf->msgh. mid. host 33333;" lpsmbuf ->msgh. mid. tid 111; QS_QCommit (thr_arg) ,- print_PTList () ,- lpsmbuf- >msgh . mode ABORT MODE; lpsmbuf- >msgh . mode COMMIT MODE;
QSjQGet (thr_arg) ,- lpsmbuf- >msgh . ode ADMINREQ_MODE; lpsmbuf - >msgh . sub_mode QADM REQ STATS, QS_QAdmin(thr_arg) ,- print_QEMT (MQEMT, 1) ;
void testjQRecov ( CHAR *qname)
HANDLE QueJFileJHandle;
BOOL Return Status; lpQEMT lpqemt ; int seg no ,- int status;
Que_File_Handle = OpenJQueueJFile (qname) ,- status = Find_Latest_QEM (QueJFileJHandle, &lpqemt, &seg_no) ; print_QEMT ( lpqemt , 1 ) ;
Return Status = CloseHandle (Que File Handle) ;
void print JQEMT ( lpQEMT lpqemt , int mode)
{ lpQEME lpqeme ;
IpPTLIST ptl_ptr; int
Diag ( " " ) ;
Diag ( "QEMT- >marker = %d" , lpqemt ->marker) ;
Diag ( "QEMT- >qem_sn. timestamp = \t%s" , ctime (klpqemt- >qem_sn . timestamp) ) ;
Diag ( "QEMT- >qem_sn. counter = %d" , lpqemt ->qem_sn. counter) ,-
Diag ("QEMT->num_segs = %d" , lpqemt ->num_segs) ;
Diag ( "QEMT- >max_entries = %d" , lpqemt ->max_entries) ;
Diag("QEMT->max_entries_limit = %d" , lpqemt->max_entries_limit) ,-
Diag ( "QEMT- >que_hd_ptr = %d" , lpqemt ->que_hd_ptr)
Diag ("QEMT- >que_tl_ptr = %d" , lpqemt- >que_tl_ptr)
Diag ("QEMT- >qget_state = %d" , lpqemt ->qget_state)
Diag ( "QEMT- >qput_state = %d" , lpqemt->qput_state)
Diag ( "QEMT- >num_pts = %d" , lpqemt- >num_pts) ;
Diag ( "QEMT- >next_avail_block . segment = %d", lpqemt - >next_avail_block . segmen ) ; Diag ( "QEMT- >next_availJblock . block = %d" , lpqem - >next_availJblock . block) ; if (mode == 1)
{ lpqeme = lpqemt ->qeme_ptr; for (i=0 ,- i<lpqemt->max entries; i++) {
Diag " " ) ; Diag " index %d" , lpqeme->index) ,- Diag "timestamp = %d" , lpqeme->timestamp) ,- Diag "MID. host = %d" , lpqeme->mid. host) ,- Diag "MID. tid = %d" , lpqeme->mid. id) ; Diag "mode = %d" , lpqeme->mode) ; Diag "flags = %d" , lpqeme- >flags) ; Diag "priority = %d" , lpqeme- >priority) ; Diag "txn_state = %d" , lpqeme->txn_state) ,- Diag "vote = %d" , lpqeme->vote) ; Diag "offset .segment = %d" , lpqeme->offset . segment) Diag "offset .block = %d" , lpqeme->offse .block) ; lpqeme++;
ptl_ptr = lpqemt->ptl_ptr; for (i=0;i<lpqemt->num pts,-i++) {
Diag ( " " ) ,- Diag ("MID. host = %d" ,ptl_ptr->mid.host) ; Diag ("MID. tid = %d",ptl_ptr->mid.tid) ; Diag ( "qeme_no = %d" ,ptl_ptr->qeme_no) ;. ptl_ptr++ ;
}
void print_QEME_txn_states ( ) lpQEME lpqeme ; char buf [10] ; int i;
Diag ( " " ) ;
Diag ( "qeme_no\t txn_state " ) ;
Diag C' \t " ) ,- lpqeme = MQEMT- >qeme_ptr ; for (i=0 ; i<MQEMT->max entries ,- i++)
{ switch (lpqeme- >txn state)
{ case INACTIVE: strcpy (buf ," INACTIVE" ) ; break; case ACTIVE: strcpy (buf , "ACTIVE" ) ; break; case INITIAL: strcpy (buf , " INITIAL" ) ; break ; case PENDING: strcpy (buf , "PENDING") ,- break; case PREPARED: strcpy (buf ," PREPARED" ) ; break; case ABORT: strcpy (buf , "ABORT") ; break; case COMMIT: strcpy (buf , "COMMIT") ; break ; case EMPTY: strcpy (buf, "EMPTY") ; break; defaul : strcpy (buf , "GARBAGE") ;
}
DiagC %d\t %s",i,buf ) ; lpqeme++ ;
Diag ( " " ) ;
void printJLREC( lpLREC lplrec)
{ DiagC1LREC->marker = %d" , lplrec- >marker) ,-
Diag ( "LREC- >seq_no . timestamp = \t%s" , ctime (&lplrec- >seq_no . timestamp) )
Diag ( "LREC- >seq_no. counter = %d" , lplrec- >seq_no. counter) ; Diag ( "LREC- >mode = %d" , lplrec- >mode) ;
Diag ( "LREC- >qeme_no = %d" , lplrec- >qeme_no) ;
Diag ( "LREC- >txn_state = Vd" , lplrec->txn_state) ;
Diag ( "LREC- >vote = %d" , lplrec->vote) ;
Diag ("LREC->mid. host = %d" , lplrec->mid.host) ;
Diag ("LREC->mid. tid = %d" , lplrec->mid. tid) ,-
Diag ( "LREC- >offset . segment = %d" , lplrec- >offset . segment) ,-
Diag ("LREC->offset. block = %d" , lplrec->offset .block) ,-
void print_SMBUF (
IpSMBUF lpsmbuf)
Diag "SMBUF->name = %s" , lpsmbuf - >name) ; Diag "SMBUF->status = %d" , lpsmbuf ->status) ,- Diag " SMBUF- >sub_status = %d" , lpsmbuf->sub_status) ,- Diag " SMBUF- >MSGH. type_coding = %d" , lpsmbuf - >msgh . type_coding) ,• Diag " SMBUF->MSGH. mode = %d" , lpsmbuf- >msgh . mode) ,- Diag " SMBUF- >MSGH . sub_mode = %d" , lpsmbuf - >msgh. sub_mode) ,- Diag " SMBUF->MSGH. flags = %d" , lpsmbuf->msgh . flags) ,-
Diag " SMBUF- >MSGH. mid. host = %d" , lpsmbuf ->msgh . mid . host ) ; Diag " SMBUF- >MSGH. mid. tid = %d" , lpsmbuf- >msgh . mid . id) ; Diag " SMBUF->MSGH. time = %d" , lpsmbuf - >msgh . time) ;
Diag " SMBUF- >MSGH . to_node = sd" , lpsmbuf ->msgh. to_node) ; Diag "SMBUF->MSGH.tO_port = sd" , lpsmbuf - >msgh . to_port ) ,- Diag "SMBUF->MSGH. to smbuf %d" , lpsmbuf- >msgh . to_smbuf)
Diag' " SMBUF- >MSGH. to_server = %s ", lpsmbuf - >msgh . to_server) ; Diag "SMBUF- >MSGH.to_logical = %s" , lpsmbuf - >msgh . to_logical ) ;
Diag "SMBUF- >MSGH. from_smbuf = %d" , lpsmbuf->msgh. from_smbuf) ; Diag "SMBUF->MSGH.reply_smbuf = %d" , lpsmbuf ->msgh . reply_smbuf) ,- Diag "SMBUF- >MSGH. size = %d" , lpsmbuf->msgh. size) ,-
Diag "SMBUF->mdat : ") ,- Diag "%s" , lpsmbuf->mdata) ,-
void print_MSGH ( lpMSGH lpmsgh)
Diag ("MSGH- >type_coding = %d" , lpmsgh- >type_coding) ; Diag ("MSGH- >mode = %d", lpmsgh- >mode) ; Diag ("MSGH- >sub_mode = %d" , lpmsgh->sub_mode) ; Diag ("MSGH- >flags = %d" , lpmsgh- >flags) ; Diag ("MSGH- >mid.host = %d" , lpmsgh->mid. host) ,- Diag ("MSGH- >mid.tid = %d" , lpmsgh- >mid. tid) ; Diag ("MSGH- >time = %d", lpmsgh->time) ,- Diag ("MSGH- >to_node = %d" , lpmsgh- >to_node) ,- Diag ("MSGH- >to_port = %d" , lpmsgh->to_port) ; Diag ("MSGH- >to_smbuf = %d" , lpmsgh->to_smbuf) ; Diag ("MSGH- >to_server = %s" , lpmsgh->to_server) ,- Diag ("MSGH- >to_logical = %s " , lpmsgh- >to_logical ) ,- Diag ("MSGH- >from smbuf = %d" , lpmsgh->from_smbuf) ,-
9Ϊ Diag ( " MSGH- >reply_smbuf = %d " , lpmsgh- >reply_smbuf ) Diag ( "MSGH - >s i ze = %d " , lpmsgh - >si ze ) ;
void print_MSGB (
CHAR * lpmsgb)
DiagC'MSGB text: ") Diag ( "%s" , lpmsgb) ;
void print RST ()
{ lpRSTSEG lprstseg; CHAR seg_str [255] ; int *msg_block; int i , j ; lprstseg = MQEMT- >rst_ptr->seg_ptr, Diag ( "Reservation Table"),- for (i=0; i<MQEMT->rst ptr->num segs; i++)
{ sprintf (seg_str, "Segment %d: ", lprstseg- >seg_no) ,- msg_block = lprstseg- >msg_block; for (j=0; j<MQEMT->rst ptr->msgs per_seg; j++)
{ sprintf (seg_str, "%s %d" , seg_str, *msg_block) ; msg block++;
} " lprstseg++; Diag("%s" , seg_str) ;
Diag ( " " ) ;
void print Active Log Lis O { - - -
CHAR seg_str [255] ; int *address, int i ;
Diag ("Active Log List : " ) ; sprintf (seg_str, " " ) ; address = Active_LREC_List->address; for (i=0; i<Active LREC List->max_txns_per_seg; i++)
{ if ( (i != 0) && ( (i%10) == 0) )
{ Diag("%s",seg_str) ,-
9Z sprintf (seg str,""),-
} sprintf (seg_str, "%s %d" , seg_str, *address) ,- address++,-
}
Diag ( " %s " , seg_str) ; Diag ( " " ) ;
void print GlobalsO
{
Diag("NUM_SEGS = %d", NUM_SEGS) ,-
Diag("MAX_ELMS = %d" , MAX_ELMS) ;
Diag("BLOCKS_PER_SEG = %d" , BLOCKS_PER_SEG)
Diag("SEGMENT_SIZE = %d", SEGMENT_SIZE) ;
Diag ("QEMT Size = %d", QEMT Size) ;
}
void print PTLis O
{ lpMTLIST ptl_ptr; lpTLIST tlist; ptl_ptr = PendingJTXNs ,-
Diag ( " " ) ,- while (ptl ptr != NULL)
( tlist = ptl_ptr->ops; Diag ( " " ) ,-
Diag ( "mid. host = %x" ,ptl_ptr->mid.host) ,- DiagC'mid.tid = %d" ,ptl_ptr->mid. tid) ,- while (tlist != NULL)
{
Diag ( "qeme_no = %d" , tlist ->qeme_no) ; tlist = tlist->next ,-
} ptl ptr = ptl_ptr->next;
void print_QAdm_Stats ( lpQADMSTATS lpstats)
{
Diag ( " " ) ;
Diag("logical_qname = %s" , lpstats->logical_qname) ; Diag("max_entries_limit = %d" , lpstats- >max_entries_limit ) ; Diag("max_entries = %d" , lpstats->max_entries) ; Diag committed_entries = %d" , lpstats- >committed_entries) ,- Diag "pending_gets = %d" , lpstats->pending_gets) ,- Diag 'pending_puts = %d" , lpstats ->pending_puts) ; Diag 'holey_entries = %d" , lpstats- >holey_entries) ; Diag num_free_entries = %d" , lpstats- >num_free_entries) ; Diag "amt_free_dspace = %d" , lpstats->amt_free_dspace) ; Diag "qget_state = %d" , lpstats- >qget_state) ; Diag "qput_state = %d" , lpstats- >qput_state) ,- Diag num_puts = %d" , lpstats->num_puts) ; Diag num_gets = %d", lpstats->num_gets) ; Diag 'num_commits = %d" , lpstats ->num_commits) ,- Diag num_aborts = %d" , lpstats ->num_aborts) ,- Diag "num_restarts = %d" , lpstats->num_restarts) ; Diag first_start_time = \t%s" , ctime (&lpstats->first_start_time) ) ,- Diag last_restart_time = \t%s" , ctime (£clpstats->last_restart time)) Diag ") ;
Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED. UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION OR DISCLOSURE.
THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
* OpenMQ
* Module: qutil.c
* Author: David Wong 9/8/95 */
// Include Files ttinclude "qlib.h" ttinclude "qserv. h" ttinclude "qadmin.h"
extern lpQEMT MQEMT; extern lpQSTR MQstate; extern lpMTLIST PendingJTXNs ,- extern int BLOCKS_PER_SEG ; extern int SEGMENT_SIZE; extern int TOT_MSG_BLOCKS ; extern int QEMT_Size; extern int QEMT_Seq_No ; extern int LREC_Seq_No; extern int NUM_SEGS ; extern int MAX_ELMS ; extern int holey_entries ; extern unsigned long QEMEJTS; extern lpLRCLST Active LREC List;
// Routine for creating queue file HANDLE Create_Queue_File (
CHAR *FileName,
CHAR *qstate, int Max_Elms , int Nuπ Segs)
HANDLE Que_File_Handle;
HANDLE Que_Sta e_Handle;
BOOL Return_Status;
DWORD dwBytesWritten;
DWORD dwPointer ;
QSTR que_state ;
// number of segments should divide // evenly among total block size NUMJSEGS = Num Segs ,- MAX_ELMS = MaxJElms,-
Update_Globals ( ) ,- if ( INVALID_HANDLEJVALUE == (QueJFileJHandle = CreateFile (FileName,
GENERICJREAD | GENERIC_WRITE , FILE_SHARE_RE D | FILE_SHARE_WRITE , NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL) ) ) return (Que_File_Handle) ,- dwPointer = SetFilePointer (Que_File_Handle,
SEGMENT_SIZE*NUM_SEGS , NULL,FILE_BEGIN) ;
SetEndOfFile (QueJFileJHandle) ; que_state.svr_state = QUEUE_SHUTDOWN; que_state.num_restarts = 0,- que_state .num_recov_tries = 0; time (&que_state . first_start_time) ,- que_state . last_restart_time = 0 ,- que_state . last_recov_time = 0 ,- if (INVALID_HANDLE_VALUE == (Que_StateJHandle = CreateFile (qstate ,
GENERIC_READ | GENERIC_WRITE , FILE_SHAREJREAD | FILE_SHARE_W ITE, NULL, CREATEJNE , FILE_ATTRIBUTE_NORMAL , NULL) ) ) return (Que_File_Handle) ,-
Return_Status = WriteFile (Que_State_Handle,
&que_state, sizeof (QSTR) , &dwBytesWritten , NULL) ,-
Return_Status = CloseHandle (Que_State_Handle) ,- return (Que File Handle);
// Routine to update global data structures, void Update GlobalsO
{ int elems_per_seg,- int temp,- elems_per_seg = (int) ceil ( (double) (MAX_ELMS/NUM_SEGS) ) ;
// Size of QEMT,- refer to qutil.h // Subject to change.
QEMT_Size = sizeof (QEMT) + (MAX_ELMS*sizeof (QEME) ) + sizeof (RST) + (NUM_SEGS*sizeof (RSTSEG) (NUM_SEGS*elems_per_seg*sizeof (int) ) + (MAX ELMS*sizeof (PTLIST) ) ;
// Total number of msg blocks in queue data file. TOT MSG BLOCKS = (MAX ELMS*sizeof (QMSG) ) /BLOCK;
// Total msg blocks consists of msg header, msg // body, and 1 log record for recording PENDING // state for each operation in a segment.
BLOCKS_PER_SEG = elems_per_seg*MSG_ENTRY_BLOCKS ;
// Include enough extra blocks to record PENDING state
// of transactional GETs and transaction ABORT/COMMIT
// records . Set this to theorectical max of MAXJELMS
// for each log record type within a single segment. temp = GET_LOG_REC_BLOCKS+TERM_LOG_RECJBLOCKS ; BLOCKS PER_SEG += (MAX_ELMS*temp) ;
// Total number of bytes in each segment .
// Currently does not include an extent factor
// for over-capacity. This will be handled
// by sysadmin interface later.
SEGMENT_SIZE = (BLOCKS_PER_SEG*BLOCK) +QEMT_Size ; return;
// Routine for opening an existing queue file HANDLE Open_Queue_File ( CHAR *FileName)
{
HANDLE Que_File_Handle; if (INVALID_HANDLE_VALUE == (Que_File_Handle = CreateFile (FileNa e,
GENERIC_READ | GENERICJWRITE, FILE_SHARE_RE D | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL) ) ) Fail ("Open_Queue_File : could not open file %s - Error = %d" ,
FileName, GetLastError () ) ; return (Que File Handle);
// Routine for deleting an existing queue file BOOL Delete_Queue_File ( CHAR *FileName)
{ return (DeleteFile (FileName) ) ;
}
int Find_Num_Entries ( lpCNTSTR *cnt ptr)
{ lpCNTSTR cptr; lpQEME lpqeme ; int qeme_no; int status; cptr = (CNTSTR *)malloc (sizeof (CNTSTR) ) ; cptr->committed = 0 ,- cptr->holey = 0 ,- qeme_no = MQEMT- >que_hd_ptr ; while (qeme no != MQEMT- >que tl ptr)
{ status = Cycle_QEME (qeme_no, klpqeme) ; switch (lpqeme- >txn state)
{ case COMMIT: cptr->committed++; break; case EMPTY: cptr->holey++ ,- break; case ACTIVE: case PENDING: break;
} qeme_no = (qeme_no+l) %MQEMT->max_entries;
status = Cycle_QEME(qeme_no, &lpqeme) ; switch (lpqeme->txn_state) case COMMIT: cptr->commit ed++; break ; case EMPTY: cptr- >holey++ ; break ,- case ACTIVE: case PENDING: break ,- }
*cnt_ptr = cptr; return(QSUCCESS) ,-
// Find QEM entry based on MID int Find QEME ( lpMID mid, int *qeme no2, lpQEME *lpqeme2)
{ lpQEME lpqeme ; int qeme no ; int valid = 1; int found = 0 ; int status ; i f ( Check Queue Empty (MQEMT ) == FALSE )
{ qeme_no = MQEMT- >que_hd_ptr; status = Cycle_QEME (qeme_no, &lpqeme) ,- while (valid && ! found)
{ if ( (lpqeme ->mid. host == mid->host) &&
(lpqeme->mid. tid == mid->tid) &&
( lpqeme- >mid. uid == mid->uid))
{ *qeme_no2 = qeme_no; *lpqeme2 = lpqeme; found = 1;
} else
{ if (qeme_no == MQEMT- >que_tl_ptr) valid = 0; else
{ qeme_no = (qeme_no+l) %MQEMT->max_entries; status = Cycle QEME (qeme no, klpqeme) ; }
if (found) return (QSUCCESS) ,- else return (QFAIL) ,-
int Cycle_QEME( int qeme_no, lpQEME *lpqeme2)
{ lpQEME lpqeme ; int l ; lpqeme = MQEMT- >qeme_ptr; for (i=0; i<qeme_no; i++) lpqeme++ ; *lpqeme2 = lpqeme; return (QSUCCESS) ;
// Routine for determining next valid // QEM entry for a PUT given that some // entries have pending GETs.
//
// Not currently used since it is // expensive. Currently keeping // track of the timestamp of last // pending get operation. // void Find_Last_Pending_Ge ( int *qeme_no) unsigned long latest_ts=0 ,- lpQEME lpqeme ; int latest_qeme=NIL; int qeme_no2 ; int status;
fo{r (qeme no2=0; qeme no2<MQEMT->max entries; qeme no2++) status = Cycle_QEME (qeme_no2 , &lpqeme) ,- if ( ( lpqeme->txn_s ate == PENDING) && (lpqeme->timestamp > latest ts) )
{ latest_ts = lpqeme->timestamp; latest_qeme = qeme_no2 ;
*qeme_no = latest_qeme;
// Routine fixes queue ptrs after aborts.
//
// Issues:
// - might need to handle deadlock
// void Fix_Que_Ptrs_on_Aborted_Put ( lpQEME lpqeme , int qeme no)
{
HANDLE hQHD, hQTL; lpQEME lpqeme2 ; int qeme_no2 ,- int status;
// Protocol is to obtain hQHD first,
// then hQTL. hQHD = OpenMutex (SYNCHRONIZE, FALSE, QUE_HD_PTR_LOCK) ; if (IhQHD)
Diag ( "QS_QCommi : Can't OpenMutex for queue head pointer lock"); if ((status = WaitForSingleObject (hQHD, QUE_LOCK_TIMEOUT) ) ! =
WAITJDBJECTJO)
Diag ( "QS_QCommi : Synch wait for queue head pointer lock failed"),- hQTL = OpenMutex (SYNCHRONIZE, FALSE, QUE_TLJPTR_LOCK) ; if (IhQTL)
Diag ( "QSjQCommi : Can't OpenMutex for queue tail pointer lock"); if ((status = WaitForSingleObject (hQTL, QUE_LOCK_TIMEOUT) ) !=
WAITJDBJECTJO)
Diag ( "QS_QCommit : Synch wait for queue tail pointer lock failed"); if (qeme no == MQEMT->que hd ptr)
{ if (MQEMT- >que hd ptr == MQEMT- >que tl ptr)
{ ~ "
MQEMT- >que_hd_ptr = NIL; MQEMT- >que tl ptr = NIL;
} else MQEMT->que hd ptr = (MQEMT- >que_hd_ptr+l ) %MQEMT- >max_entries ;
} else if (qeme no == MQEMT- >que tl_ptr)
{ qeme_no2 = qeme_no,- lpqeme2 = lpqeme ,- while ( (lpqeme2->txn_state == EMPTY) && (qeme no2 != MQEMT->que hd ptr))
{ qeme_no2 = (MQEMT- >max_entries+qeme_no2 - 1 ) %MQEMT- >max_entries ; status = Cycle QEME (qeme no2 , &lpqeme2 ) ; } if ( (qeme_no2 == MQEMT- >que_hd_ptr) && ( lpqeme2 - >txn state == EMPTY) )
{
MQEMT- >que_hd_ptr = NIL; MQEMT- >que_tl_ptr = NIL; else MQEMT- >que tl ptr = qeme no2; } " "
ReleaseMutex (hQTL) ; ReleaseMutex (hQHD) ;
/*
*/
Diag("Fix_on_AbortedJPut : qeme_no = %d, head = %d, tail = %d" , qeme_no , MQEMT- >que_hd_ptr , MQEMT- >que_tl_ptr) ,- // Routine fixes queue ptrs after aborts . // Use QEME timestamps for comparison .
//
// Issues :
// - might need to handle deadlock // void Fix_Que_Ptrs_on_Aborted_Get ( int qeme no)
{
HANDLE hQHD , hQTL ; lpQEME lpqeme , hd_qeme , tl_qeme ,- int status; hQHD = OpenMutex (SYNCHRONIZE, FALSE, QUE_HD_PTRJLOCK) ,- if (IhQHD)
Diag ( "QS_QCommit : Can't OpenMutex for queue head pointer lock"); if ((status = WaitForSingleObject (hQHD, QUE_LOCK_TIMEOUT) ) ! =
WAITJDBJECTJO)
Diag ( "QSjQCommit : Synch wait for queue head pointer lock failed") hQTL = OpenMutex (SYNCHRONIZE, FALSE, QUEJTL_PTR_LOCK) ; if (IhQTL)
Diag ( "QS_QCommit : Can't OpenMutex for queue tail pointer lock"); if ((status = WaitForSingleObjec (hQTL, QUEJLOCKJTIMEOUT) ) !=
WAITJOBJECTJO)
Diag ( "QS_QCommit : Synch wait for queue tail pointer lock failed") if (MQEMT- >que hd ptr == NIL)
{ " ~
MQEMT- >que_hd_ptr = qeme_no; MQEMT- >que tl ptr = qeme no;
} else
{ status = Cycle_QEME (qeme_no, δdpqeme) ,- status = Cycle_QEME (MQEMT- >que_hd_ptr, &hd_qeme) ; status = CyclejQEME (MQEMT- >que_tl_ptr, &tl_qeme) ; if (lpqeme->timestamp < hd_qeme->timestamp) MQEMT- >que_hd_ptr = qeme_no,- else if (lpqeme->timestamp > tl_qeme->timestamp) MQEMT- >que_tl_ptr = qeme_no,-
ReleaseMutex (hQTL) ; ReleaseMutex (hQHD) ,-
/* */
Diag ( "Fix_on_Aborted_Get : qeme_no = %d, head = %d, tail = %d", qeme_no , MQEMT- >que_hd_ptr , MQEMT- >que_tl_p r) ,-
}
// Routine for fetching next // valid GET QEM entry slot. // Not currently used, int Fetch_Next_Get_Slot ( int *qeme_no) lpQEME lpqeme ,- int done=0 ; int found=0 ,- int qeme no2 ; int status; qeme_no2 = MQEMT- >que_hd_ptr ,- while (Idone && ! found)
{ status = Cycle_QEME (qeme_no2 , &lpqeme) ,- if ( (lpqeme ->mode == PUT_MODE) &&
(lpqeme->txn state == COMMIT))
{ *qeme_no = qeme_no2 ; found = 1 ;
} else
{ if (qeme_no2 == MQEMT- >que_tl_ptr) done = 1 ; else qeme no2 = (qeme no2+l) %MQEMT- >max_entries ;
} } if (found) return (QSUCCESS) ; else return (QFAIL)
// Routine for fetching next // valid PUT QEM entry slot. // Not currently used, int Fetch_Next_Put_Slo ( int *qeme_no) lpQEME lpqeme ,- int done=0 ,- int found=0; int qeme_no2 ,- int status; qeme_no2 = MQEMT- >que_tl_ptr;
U U U 1 v while ( !done)
{ status = Cycle_QEME (qeme_no2 , Sdpqeme) ; if ( lpqeme- >txn state == EMPTY)
{ *qeme_no = qeme_no2 ,- found = 1 ;
} else
{ if (qeme_no2 == MQEMT- >que_hd_ptr) done = 1 ; else qeme no2 = (qeme no2+l) %MQEMT->max entries,- } } if (found) return (QSUCCESS) ; else return (QFAIL) ,-
// Routine for resetting QEME timestamps // starting from 1 after after recovery or // at queue server shutdown. Point is to // guide against timestamp ever exceeding // the max of an unsigned long. void Update QEME TS ( )
{
HANDLE hQEME ; lpQEME lpqeme ; int status; int qeme_no,- int done=0; hQEME = OpenMutex (SYNCHRONIZE, FALSE, QEMEJTSJGENJLOCK) ; if (! hQEME)
Diag("Update_QEME_TS: Can't OpenMutex for QEMEJTS Lock"); if ((status = WaitForSingleObject (hQEME, QUEJLOCKJTIMEOUT) ) !=
WAITJDBJECT_0)
Diag("Update_QEME_TS: Synch wait for QEMEJTS Lock failed"),-
QEMEJTS = 1; qeme_no = MQEMT- >que_hd_ptr ; while ( Idone)
{ status = Cycle_QEME (qeme_no, Sclpqeme) ; lpqeme- >timestamp = QEMEJTS++; if (qeme_no == MQEMT- >que_tl_ptr) done = 1 ; else qeme no = (qeme no+1) %MQEMT->max_entries,-
}
ReleaseMutex (hQEME) ,-
} // Routine for finding most current // QEM Table in queue data file. int Find_Latest_QEM(
HANDLE Que_File_Handle, lpQEMT *lpqemt2, int *seg_num)
{ lpQEMT lpqemt ; lpQEME lpqeme ; lpRST lprst;
IpRSTSEG lprstseg; lpPTLIST ptl_ptr;
BOOL Return_Status;
DWORD dwPointer;
DWORD dwBytesRead;
SN curr_qem_sn ;
SN prev_qem_sn; int tseq_no=0; int done=0,i; int elems_per_seg; curr_qem_sn. timestamp = 0 ; curr_qem_sn. counter = 0; prev_qem_sn. timestamp = 0 ,- prev_qem_sn. counter = 0 ; lpqemt = (QEMT *) malloc (sizeof (QEMT) ) ,- dwPointer = SetFilePointer (Que_File_Handle ,
0,NULL,FILE_BEGIN) ; if ( ! (Return_Status = ReadFile (Que_File_Handle, lpqemt , sizeof (QEMT) , SdwBytesRead, NULL) ) ) Fail ("Find_Latest_QEM: could not read QEMT buffer - Error = %d" ,
GetLastError () ) ; curr_qem_sn. imestamp = lpqemt ->qem_sn. timestamp ; curr_qem_sn. counter = lpqemt ->qem_sn. counter,-
NUM_SEGS = lpqemt->num_segs; MAX_ELMS = lpqemt ->max_entries ; tseq_no++ ; elems_per_seg = (int) ceil ( (double) (MAX_ELMS/NUM_SEGS) ) ;
Update_Globals() ,- lpqeme = (QEME *) malloc (MAX_ELMS*sizeof (QEME) ) ; lprst = (RST *) malloc (sizeof (RST) ) ; lprstseg = (RSTSEG *) malloc (NUM_SEGS*sizeof (RSTSEG) ) ; lprs ->num_segs = NUM_SEGS; lprst->msgs_per_seg = elems_per_seg; lprst- >seg ptr = lprstseg; for (i=0; i<NUM SEGS; i++)
{ lprstseg- >seg_no = i; lprstseg- >msg_block =
(int *) malloc (elems_per_seg*sizeof (int) ) ,- lprstseg++ ;
} ptl_ptr = (PTLIST *) malloc (MAX_ELMS*sizeof (PTLIST) ) ; while ( !done)
{ dwPointer = SetFilePointer (Que_File_Handle, tseq_no*SEGMENT_SIZE, NULL,FILE_BEGIN) ; if ( ! (Return_Status = ReadFile (Que_File_Handle, lpqemt , sizeof (QEMT) , SdwBytesRead, NULL) ) ) Fail ("Find_Latest_QEM: could not read QEMT buffer - Error = %d" ,
GetLastError ( ) ) ; if ( (lpqem ->marker == QEMTMARK) &&
Bigger_Seq_No (&lpqemt->qem_sn, icurr_qem_sn) ) prev_qem_sn. timestamp = curr_qem_sn. timestamp ,- prev_qem_sn . counter = curr_qem_sn. counter ; curr_qem_sn. timestamp = lpqemt ->qem_sn. timestamp ,- curr_qem_sn. counter = lpqemt ->qem_sn. counter,- tseq no = (tseq no+l)%NUM SEGS;
} else done = 1;
} tseq_no = (NUM_SEGS+tseq_no-l) %NUM_SEGS; dwPointer = SetFilePointe (Que_File_Handle, tseq_no*SEGMENT_SIZE, NULL,FILE_BEGIN) ; if ( ! (Return_Status = ReadFile (Que_File_Handle, lpqemt, sizeof (QEMT) , &dwBytesRead,NULL) ) ) Fail ("Find_Latest_QEM: could not read QEMT buffer - Error = %d" ,
GetLastError 0 ) ; if ( ! (Return_Status = ReadFile (Que_File_Handle, lpqeme,
MAX_ELMS*sizeof (QEME) , &dwBytesRead,NULL) ) ) Fail("Find_Latest_QEM: could not read QEME buffer - Error = d",
GetLastError () ) ; if ( ! (Return_Status = ReadFile (Que_File_Handle, lprst, sizeof (RST) , kdwBytesRead, NULL) ) ) Fail ("Find_Latest_QEM: could not read in RST structure - Error = %d", GetLastError () ) ,- lprstseg = lprst->seg_ptr; for (i=0; i<lprst->num segs; i++)
{ if (! (Return Status = ReadFile (Que File_Handle, lprstseg, sizeof (RSTSEG) , &dwBytesRead,NULL) ) ) Fail ( "Find_Latest_QEM: could not read in RSTSEG structure - Error = %d" , GetLastError () ) ; if ( ! (Return_Status = ReadFile (Que_File_Handle, lprstseg- >msg_block, lprs ->msgs_per_seg*sizeof (int) , &dwBytesRead,NULL) ) ) Fail ( "Find_Latest_QEM: could not read in msg_block entries - Error = %d" , GetLastError () ) ,- lprstseg++; } if ( ! (Return_Status = ReadFile (Que_File_Handle, ptl_ptr,
MAX_ELMS*sizeof (PTLIST) , &dwBytesRead,NULL) ) ) Fail ("Find_Latest_QEM: could not read PTLIST buffer - Error = %d",
GetLastError () ) ; lpqemt ->qeme_ptr = lpqeme; lpqemt ->rst_ptr = lprst; lpqemt ->ptl_ptr = ptl_ptr;
*lpqemt2 = lpqemt; *seg_num = tseq_no; return (QSUCCESS) ;
int Create_QEMT ( lpQEMT *lpqemt, int max elms)
{ lpQEMT lpqemt2 ; lpRSTSEG lprstseg; int i, elems_per_seg; elems_per_seg = (int) ceil ( (double) (MAX_ELMS/NUM_SEGS) ) ;
lpqemt2 = (QEMT *) malloc (sizeof (QEMT) ) ; lpqemt2->qeme_ptr = (QEME *) malloc (max_elms*sizeof (QEME) ) ; lpqemt2->rst_ptr = (RST *) malloc (sizeof (RST) ) ,- lpqemt2->rst_ptr->seg_ptr =
(RSTSEG *) malloc (NUM_SEGS*sizeof (RSTSEG) ) ; lpqemt2->rst_ptr->num_segs = NUM_SEGS; lpqemt2->rst_ptr->msgs_per_seg = elems_per_seg; lprstseg = lpqemt2->rst_ptr->seg_ptr; for (i=0; i<NUM SEGS; i++) { lprstseg- >seg_no = i ,- lprstseg- >msg_block =
(int *) malloc (elems_per_seg*sizeof (int) ) ,- lprstseg++;
} lpqemt2->ptl_ptr = (PTLIST *) malloc (max_elms*sizeof (PTLIST) ) ; *lpqemt = lpqemt2; return (QSUCCESS) ,-
int Init_QEMT( lpQEMT lpqemt , int iiax elms, int ext elms, int num_segs) t2 ; e ,- tr; seg; lock;
Figure imgf000110_0001
lpqemt2 = lpqemt;
Gen_QEM_Seq_No ( &lpqemt2 - >qem_sn) ,- lpqemt2->marker = QEMTMARK; lpqemt2->num_segs = num_segs ,- lpqemt2->max_entries = max_elms; lpqemt2->max_entries_limit = max_elms+ext_elms,- lpqemt2->next_avail_block. segment = 0; lpqemt2->next_avail_block. block = 0; lpqemt2->que_hd_ptr = NIL; lpqemt2->que_tl_ptr = NIL; lpqemt2->qget_state = ENABLED; lpqemt2->qput_state = ENABLED; lpqeme = lpqemt2->qeme_ptr; for (i=0; i<lpqemt2->max_entries; i++)
{ lpqeme- >index = i; lpqeme- >timestamp = 0; lpqeme->mid. host = 0; lpqeme->mid. tid = 0; lpqeme->mid.uid = 0, lpqeme->mode = 0, lpqeme- >flags = 0; lpqeme- >priority = 0; lpqeme- >txn_state = EMPTY; lpqeme->vote = 0; lpqeme- >offset .segment = 0; lpqeme- >offse .block = 0 ; lpqeme++ ; } lprstseg = lpqemt2->rst_ptr->seg_ptr; for (i=0; i<NUM SEGS; i++)
{ msg_block = lprstseg- >msg_block; fo{r (j=0; j<lpqemt2->rst-ptr->msgs-per-seg; j++)
*msg_block = NIL; msg block++;
} lprstseg++;
} lpqemt2->num_pts = 0; ptl_ptr = lpqemt2- >ptl_ptr; for (i=0; i<lpqemt2->max_entries; i++) ptl_ptr->mid.host = 0 ; ptl_ptr->mid. tid = 0 ; ptl_ptr->qeme_no = NIL; ptl_ptr++ ;
return (QSUCCESS) ,-
}
int Write_QEMT(
HANDLE Que_File_Handle, int seg_no, lpQEMT lpqemt)
{ lpRSTSEG lprstseg;
BOOL Return_Status;
DWORD dwPointer;
DWORD dwBytesWritten,- int status; int i ; status = Gen_LREC_Seq_No (&lpqemt->lrec_sn) ;
Conv_from_MTlist () ,- dwPointer = SetFilePointer (Que_File_Handle,
(LONG) (seg_no*SEGMENT_SIZE) , NULL,FILE_BEGIN) ; if ( ! (Return_Status = WriteFile (Que_FileJHandle, lpqemt, sizeof (QEMT) ,
&dwBytesWritten,NULL) ) ) Fail ("Write_QEMT: could not write out QEM Table - Error = %d" ,
GetLastError ( ) ) ; if ( ! (Return_Status = WriteFile (Que_File_Handle, lpqemt->qeme_ptr, lpqemt->max_entries*sizeof (QEME) , &dwBytesWrit en,NULL) ) ) Fail ("Write_QEMT: could not write out QEM entries - Error = %d", GetLastError 0 ) ; if ( ! (Return_Status = WriteFile (Que_File_Handle, lpqemt- >rst_ptr, sizeof (RST) , &dwBytesWritten,NULL) ) ) Fail ( "WritejQEMT: could not write out RST structure - Error = %d" , GetLastError ( ) ) ; lprstseg = lpqemt ->rst_ptr->seg_ptr ; for (i=0; i<lpqemt->rst ptr->num segs; i++)
{ if ( ! (Return_Status = WriteFile (Que_File_Handle, lprstseg, sizeof (RSTSEG) , &dwBytesWritten,NULL) ) ) Fail ("Write_QEMT: could not write out RSTSEG -structure - Error = %d" , GetLastError () ) ,- if ( ! (Return_Status = WriteFile (Que_File_Handle, lprstseg- >msg_block, lpqemt->rst_ptr->msgs_per_seg*sizeof (int) , &dwBytesWritten,NULL) ) ) Fail ( "Write_QEMT: could not write out msgjblock entries - Error = %d" , GetLastError ( ) ) ,- lprstseg++ ,- } if ( ! (Return_Status = WriteFile (Que_File_Handle , lpqem ->ptl_ptr, lpqemt->num_pts*sizeof (PTLIST) , &dwBytesWritten,NULL) ) ) Fail ("WritejQEMT: could not write out PT list - Error = %d" , GetLastError ( ) ) ,-
// Now, write out the most current log record timestamp. return (QSUCCESS) ,-
int RetrieveJQEMT (
HANDLE Que File Handle, int seg_no , lpQEMT *lpqemt2) lpQEMT lpqemt ,- lpQEME lpqeme ; lpRST lprst; lpRSTSEG lprstseg; lpPTLIST ptl ptr;
BOOL Return_Status ,-
DWORD dwPointer;
DWORD dwBytesRead; int elems_per seg;" int i;
OO O l l O elems_per_seg = (int) ceil { (double) (MAX_ELMS/NUM_SEGS) ) ; lpqemt = (QEMT *) malloc (sizeof (QEMT) ) ; lpqeme = (QEME *) alloc (MAX_ELMS*sizeof (QEME) ) ; lprst = (RST *) malloc (sizeof (RST) ) ; lprstseg = (RSTSEG *) malloc (NUM_SEGS*sizeof (RSTSEG) ) ; lprst ->num_segs = NUM_SEGS; lprst ->msgs_per_seg = elems_per_seg; lprstseg = lprst ->seg_ptr,- for (i=0; i<NUM SEGS; i++)
{ lprstseg- >seg_no = i; lprstseg- >msg_block =
(int *)malloc (elems_per_seg*sizeof (int) ) ; lprstseg++;
} ptl_ptr = (PTLIST *) malloc (MAX_ELMS*sizeof (PTLIST) ) ; dwPointer = SetFilePointer (Que_File_Handle,
(LONG) (seg_no*SEGMENT_SIZE) , NULL, FILE_BEGIN) ;
if ( ! (ReturnjStatus = ReadFile (Que_File_Handle , lpqemt , sizeof (QEMT) , &dwBytesRead,NULL) ) ) Fail ( "Retrieve_QEMT: could not read QEMT Table - Error = %d" ,
GetLastErro () ) ; if ( ! (ReturnjStatus = ReadFile (Que_File_Handle, lpqeme, lpqemt->max_entries*sizeof (QEME) , &dwBytesRead,NULL) ) ) Fail ("Retrieve_QEMT: could not read QEME entries - Error = %d" ,
GetLastError () ) ; if ( ! (ReturnjStatus = ReadFile (Que_File_Handle, lprst , sizeof (RST) ,&dwBytesRead,NULL) ) ) Fail ("Write_QEMT: could not write out RST structure - Error = %d" , GetLastError () ) ; lprstseg = lprst ->seg_ptr; for (i=0; i<lprst->num_segs; i++) if ( ! (Return_Status = ReadFile (Que_File_Handle, lprstseg, sizeof (RSTSEG) , &dwBytesRead,NULL) ) ) Fail ("Write_QEMT: could not write out RSTSEG structure - Error = %d" , GetLastError () ) ; if ( ! (Return_Status = ReadFile (Que_File_Handle, lprstseg- >msg_block, lprst->msgs_per_seg*sizeof (int) , &dwBytesRead,NULL) ) ) Fail ("Write QEMT: could not write out msg_block entries - Error = %d"; GetLastError () ) ; lprstseg++; } if ( ! (Return_Status = ReadFile (Que_File_Handle,ptl_ptr, lpqemt- >num_pts*sizeof (PTLIST) , &dwBytesRead,NULL) ) ) Fail ("Retrieve_QEMT: could not read PT list - Error = %d" ,
GetLastError () ) ; lpqemt ->qeme_ptr = lpqeme; lpqemt ->rst_ptr = lprst; lpqemt ->ptl_ptr = ptl_ptr;
*lpqemt2 = lpqemt;
// Conv_to_MTlist () ; return (QSUCCESS) ;
int Retrieve_Msg_Hdr (
HANDLE Que_File_Handle, BLAD Msg_Addr, lpMSGH Msg_Hdr)
{
BOOL Return_Status;
DWORD dwBytesRead;
DWORD dwPointer;
LONG Dist_to_Move;
Conv_Addr (&Dist_to_Move, &Msg_Addr) ,- dwPointer = SetFilePointer (Que_File_Handle,
Dist_to_Move , NULL, FILE_BEGIN) ;
Return_Status = ReadFile (Que_File_Handle,
Msg_Hdr, MSG_HDR_SIZE, &dwBytesRead, NULL) ; if ( (Return_Status == TRUE) && (dwBytesRead == MSG_HDR_SIZE) ) return (QSUCCESS) ; else return (QFAIL) ,-
int Write_Msg_Hdr (
HANDLE Que_File_Handle, BLAD Msg_Addr , lpMSGH Msg_Hdr) BOOL ReturnjStatus;
DWORD dwBytesWritten;
DWORD dwPointer;
LONG Dist_to_Move;
Conv_Addr (&Dist_to_Move, &Msg_Addr) ; dwPointer = SetFilePointer (Que_File_Handle,
Dist_to_Move , NULL, FILE_BEGIN) ;
Return_Status = WriteFile (Que_File_Handle,
Msg_Hdr, MSG_HDR_SIZE, &dwBytesWritten , NULL) ; if ( (Return_Status == TRUE) && (dwBytesWritten = MSG HDR SIZE) return (QSUCCESS) ; else return (QFAIL) ,-
int Retrieve_Msg_Body (
HANDLE Que File Handle,
BLAD Msg_Addr,
DWORD Msg_Length,
CHAR *Msg_Body)
BOOL ReturnjStatus ;
LONG Dist_to_Move;
DWORD dwBytesRead;
DWORD dwPointer;
Conv_Addr (&Dist_to_Move , &Msg_Addr) ; dwPointer = SetFilePointer (Que_File_Handle,
Dist_to_Move, NULL, FILE_BEGIN) ;
Return_Status = ReadFile (Que_File_Handle,
Msg_Body, Msg_Length, &dwBytesRead, NULL) ; if ( (Return_Status == TRUE) && (dwBytesRead == Msg_Length) ) return (QSUCCESS) ; else return (QFAIL) ,-
int Write_Msg_Body (
HANDLE Que_File_Handle, BLAD Msg_Addr, DWORD Msg_Length, CHAR *Msg_Body)
BOOL Return_Status ;
LONG DistjcoJMove;
DWORD dwBytesWritten;
DWORD dwPointer;
Conv_Addr ( &Dis _to_Move , &Msg_Addr) ,- dwPointer = SetFilePointer (Que_File_Handle,
Dist_to_Move , NULL, FILE_BEGIN) ;
Return_Status = WriteFile (Que_File_Handle,
Msg_Body, Msg_Length, kdwBytesWritten, NULL) ; if ( (Return_Status == TRUE) && (dwBytesWritten == MsgJLength) return (QSUCCESS) ,- else return (QFAIL) ;
int Retrieve_Msg (
HANDLE Que_File_Handle, BLAD Msg_Addr , lpQMSG qmsg)
BOOL ReturnjStatus;
LONG Dist_tO_Move;
DWORD dwBytesRead;
DWORD dwPointer;
Conv_Addr ( &Dist_to_Move , &Msg_Addr) ; dwPointer = SetFilePointer (QueJFileJHandle,
Dist_to_Move , NULL,FILE_BEGIN) ;
Return_Status = ReadFile (QueJFileJHandle, qmsg, sizeof (QMSG) , &dwBytesRead,NULL) ,- if ( (Return_Status == TRUE) && (dwBytesRead == sizeof (QMSG) ) ) return (QSUCCESS) ; else return (QFAIL) ;
int Retrieve_Log_Rec (
HANDLE Que_File_Handle,
BLAD LREC_Addr, 0114 lpLREC LREC_ptr)
BOOL Return_Status,-
DWORD dwBytesRead;
LONG Dist_to_Move;
DWORD dwPointer;
Conv_Addr ( &Dist_to_Move , &LREC_Addr) ; dwPointer = SetFilePointer (QueJFileJHandle,
Dist_to_Move , NULL, FILE_BEGIN) ;
Return_Status = ReadFile (QueJFileJHandle,
LREC_ptr,
LOG_REC_BLOCKS*BLOCK, &dwBytesRead, NULL) ; if ( (Return_Status == TRUE) &&
(dwBytesRead == (LOG_REC_BLOCKS*BLOCK) ) ) return (QSUCCESS) ; else return (QFAIL) ,-
int Write_Log_Rec (
HANDLE Que_File_Handle, BLAD LREC_Addr, lpLREC LREC_ptr)
{
BOOL Return_Status;
DWORD dwBytesWritten;
DWORD dwPointer;
LONG Dist_to_Move;
Conv_Addr (&Dist_to_Move, &LREC_Addr) ; dwPointer = SetFilePointer (Que_File_Handle,
Dist_to_Move, NULL, FILE_BEGIN) ;
Return_Status = WriteFile (Que_File_Handle,
LRECjptr,
LOG_REC_BLOCKS*BLOCK, &dwBytesWritten , NULL) ; if (Return_Status == FALSE)
DiagC'Error Code = %d" , GetLastError ()) ;
if ( (Return_Status == TRUE) &&
(dwBytesWritten == (LOG_REC_BLOCKS*BLOCK) ) ) return (QSUCCESS) ; else return (QFAIL) ,-
00011^
void Init Active LREC List() { - - - int i ,- int *address; address = Active_LREC_List->address ,- for (i=0; i<Active_LREC_List->max_txns_per_seg; i++)
{ ♦address = NIL; address++ ,-
int msg_entry_comp ( const void *argl, const void *arg2)
{ if (*(int*)argl < *(int*)arg2) return (-1) ; else if (*(int*)argl == *(int*)arg2) return (0) ,- else if (*(int*)argl > *(int*)arg2) return (1) ,-
void Sort_RST_Entries ( int seg_no)
{ lpRSTSEG lprstseg; int i ; lprstseg = MQEMT- >rst_ptr->seg_ptr ; for (i=0; i<seg_no; i++) lprstseg++; qsort ( (void *) lprstseg- >msg_block,
(size_t) MQEMT- >rst_ptr->msgs_per_seg, sizeof (int) ,msg_entry_comp) ;
}
int Add_RST_Entry ( int seg_no, int entry value)
{ lpRSTSEG lprstseg; int found=0 ; _ int i=0,- int *msgJblock; lprstseg = MQEMT->rst_ptr->seg_ptr,- for (i=0; i<seg_no; i++) lprstseg++ ,- msg_block = lprstseg- >msg_block; while (Ifound && (i < MQEMT- >rst_ptr- >msgs_per_seg) )
{ if (*msg_block == NIL) found = 1 ,- else
{ i++; msg block++;
if (found)
*msg_block = entry_value; return (found) ;
}
int DelJRSTJEntry ( int seg_no, int entry_value)
{ lpRSTSEG lprstseg; int found=0; int i ; int *msg_block; lprstseg = MQEMT->rst_ptr->seg_ptr; for (i=0; i<seg_no,- i++) lprstseg++; i = 0; msg_block = lprstseg- >msg_block; while (Ifound && (i < MQEMT- >rst_ptr->msgs_per_seg) )
{ if (*msgJblock == entry_value) found = 1; else
{ i++; msg block++;
if (found)
*msg_block = NIL; return (found) ; int Entry_in_RST( int seg_no, int entry value)
{ lpRSTSEG lprstseg; int found=0; int i=0; int *msg_block,- lprstseg = MQEMT- >rst_ptr->seg_ptr, for (i=0; i<seg_no,- i++) lprstseg++; msg_block = lprstseg- >msgJblock; while (Ifound && (i < MQEMT->rst ptr->msgs per seg)
{ if (*msg_block == entry_value) found = 1 ; else
{
1 ++; msg block++; } "
return (found) ;
}
int log_entry_comp ( const void *argl, const void *arg2)
{ if (*(int*)argl < *(int*)arg2) return (1) ; else if (*(int*)argl == *(int*)arg2) return (0) ; else if (*(int*)argl > *(int*)arg2) return (-1) ;
void Sort Log Entries ()
{ " _ qsort ( (void * ) Active_LREC_List - >address ,
(sizejt) Active_LREC_List->max_txns_per_seg, sizeof (int) , log entry comp) ,-
}
int Add_Log_Entry ( int entry_value) 000 1 1 8 int found=0 ; int i=0; int *address; address = Active_LREC_List->address; while (Ifound && (i<Active LREC_List->max txns_per_seg) )
{ if (*address == NIL) found = 1 ,- else
{ 1 + +; address ++;
, ! if (found)
*address = entry_value; return (found) ,-
int Del_Log_Entry ( int entry value) { int found=0 ,- int i=0; int *address ; address = Active_LREC_List->address; while (Ifound && (i<Active LREC List->max_txns_per_seg) )
{ if (*address == entry_value) found = 1; else
{ i++; address++;
if (found)
*address = NIL; return (found) ,-
int In_Log_Rec_List ( int start, int end, int *hit) int found=0 ; int i=0; int address; address = Active_LREC_List->address; while (Ifound &&
(i<Active_LREC_List->max_txns_per_seg) &&
(♦address != NIL) )
{ if ((*address >= start) && (*address <= end))
{ *hit = *address; found = 1 ;
} else
{ i + +; address + +,-
return (found) ;
int Cycle_RST_Seg( int seg_no,
IpRSTSEG *lprstseg2)
{
IpRSTSEG lprstseg; int i ,- lprstseg = MQEMT- >rst_ptr->seg_ptr; for (i=0; i<seg_no,- i++) lprstseg++; *lprstseg2 = lprstseg; return (QSUCCESS) ,-
int Get_Next_BLAD (
HANDLE Que_File_Handle, int type , BLAD *offset)
{
IpRSTSEG lprstseg; int end=0,- int found=0; int notfull=l; int moved=0 ; int cycled=0; int start=l; int holes=0; int status ,- int conflict; int *msg_block, *msg_block2 ; int msg_num; int currJblock; int orig_seg, curr_seg; int blocks_needed; if (type == MSG_WRITE) blocks_needed = MSGJENTRYJBLOCKS ,- else blocks_needed = LOGJRECJBLOCKS; orig_seg = MQEMT- >next_availJblock. segment ,- curr_seg = MQEMT- >next_avail_block. segment ,- curr_block = MQEMT- >next_avail_block . block; status = Cycle_RST_Seg (curr_seg, klprstseg) ; msg_num = 0 ,- msg_block = lprstseg- >msg_block; msg_block2 = msg_block; msg_block2++ ,-
while (notfull && Ifound)
{ while ( (msg_num < MQEMT- >rst_ptr- >msgs_per_seg) && (*msg block == NIL) )
{ msg_num++ ; msg_block++ ; holes++ ;
/*
Diag ( "segment = %d, currjblock = %d, msgJblock = %d, msg_block2 = %d, msg_r */
if{ (msg num == MQEMT->rst-ptr->msgs-per-seg) if (moved) currjblock = 0 ,- if ( (curr_block+blocks_needed) > BLOCKS_PER_SEG) end = 1 ; else
{ while (Ifound && ((curr block+blocks_needed) <= BLOCKS_PER_SEG) )
{ if ( ! In_Log_Rec_List (currjblock, curr_block+blocks_needed , ^conflict) ) found = l ,- else curr block = conflict+1;
if (Ifound) end = 1 ,-
if (msg_num == (MQEMT- >rst_ptr- >msgs_per_seg- l ) ) if (moved) cur jblock = 0 ,- while (Ifound && ( (curr_block+blocks_needed) <= *msg_block) if ( ! In_LogJRec_List (curr_block, curr_block+blocks_neede , &conflict) ) found = 1 ,- else curr block = conflict+1;
if (I found) curr_block = *msg_block+MSGJENTRY_BLOCKS ; while (Ifound && ( (curr_block+blocks_needed) <= BLOCKS_PER_SEG) ) if ( I In_Log_Rec_List (curr_block, curr_block+blocks_needed, &conflict) ) found = 1; else curr block = conflict+1; } if (Ifound) end = 1 ,-
if (msg num < (MQEMT->rst ptr->msgs per seg-1) )
{ ~ if (moved) curr_block = 0 ,- msg_block2 = msg_block; msg_block2++; while (Ifound && (msg num < (MQEMT- >rst_ptr->msgs_per seg-1)))
{ if (moved && start)
{ while (Ifound && ((curr block+blocks_needed) <= *msg_block)
{ if ( I InJLogJRecJList (curr_block, curr_block+blocks_needed, ^conflict) ) found = 1 ,- else curr block = conflict+1;
} start = 0 ; } if ( I found) curr_block = *msg_block+MSG_ENTRY_BLOCKS ; while ( I found && ( (curr_block+blocks_needed) <= *msg_block2 ) ) if ( I In_Log_Rec_List ( curr_block , curr _block+blocks_needed , &conflict ) ) found = 1 ; else curr block = conflict+1 ; } if (Ifound)
{ msg_num++ ; msg_block++ ; if (msg_num < (MQEMT->rst_ptr->msgs_per_seg-l) ) msg_block2 = msg_block; msg block2++;
} else
{ curr_block = *msg_block+MSG_ENTRY_BLOCKS; while (Ifound && ((curr block+blocks needed) <= BLOCKS PER SEG)
{ ~ ~ if ( I In_Log_Rec_List (curr_block, curr_block+blocks_needed, {.conflict) ) found = 1 ; else currjblogk = conflict+1;
// end while if (Ifound) end = 1;
if (end)
{ moved = 1 ,- start = 1 ; if (cycled) no full = 0; else curr_seg = (curr_seg+l) %MQEMT->num_segs,- if ( I cycled)
{ if (curr_seg == orig_seg) cycled = 1;
// Flush out QEMT and zero out // active log record list.
MQEMT- >next avail block . segment = (MQEMT- >next_avail_block . segment+1 ) MQEMT- >num_segs ; curr_block = 0 ,-
MQEMT- >next_avail_block. block = 0; status = Gen_QEM_Seq_No (& (MQEMT- >qem_sn) ) ; status = Write_QEMT(Que_FileJHandle,
MQEMT- >next_avail_block . segment , MQEMT) ;
Init_Active_LREC_List () ; status = Cycle_RST_Seg (curr_seg, klprstseg) ; msg_num = 0 ; msg_block = lprstseg- >msg_block; msg_block2 = msgjblock; msgJblock2++; end = 0;
} // end if (end)
} // while (notfull && Ifound)
if (found) {
/*
Diag ("Allocated Space: segment = %d, block = %d" , curr_seg, curr_block) */ offset->segment = MQEMT- >next_avail_block . segment ,- offset->block = currjblock;
MQEMT- >next_avail_block. block = curr_block + blocks_needed; holey_entries = 0 ; if (type == MSG WRITE)
{ if ( !Add_RST_Entry (offset->segment ,offset->block) ) notfull = 0; else Sort RST Entries (offset->segment) ,-
} ~ " else if (type == LOG WRITE)
{ if ( !Add_Log_Entry (offset->block) ) notfull = 0; else Sort Log Entries (offset->segment) ,-
. ' else
{ holey_entries = holes; offset->segment = NIL; offset->block = NIL; } return (notfull) ,-
}
BOOL Check_QueueJFul l ( lpQEMT lpqemt )
{ lpQEME lpqeme ;
BOOL Full=TRUE; int status; int cnt ,- if ( lpqemt ->que_hd_ptr == NIL) Full = FALSE; else if ( ( (lpqemt->que_tl_ptr+l) %lpqemt->max_entries) == lpqemt ->que hd ptr)
{ status = CycleJQEME (lpqemt - >que_hd_ptr , klpqeme) ,- if ( lpqeme ->txn_state == EMPTY)
Full = FALSE;
} else
{ lpqeme = lpqemt ->qeme_ptr; cnt = 0 ; while (Full && (cnt < lpqemt->max entries))
{ if ( lpqeme- >txn_state == EMPTY)
Full = FALSE; else
{ cnt ++ ,- lpqeme++ ;
return (Full) ;
}
BOOL Check_Queue_Empty ( lpQEMT lpqemt) if ( lpqemt ->que_hd_ptr == NIL) return (TRUE) ,- else return (FALSE) ,-
void Conv from MTlistO
{ " ~ lpPTLIST pl,p2; lpTLIST tl; lpMTLIST ml; int cnt = 0 ,- pi = (PTLIST *)malloc(MQEMT->max_entries*sizeof (PTLIST) ) ml = PendingJTXNs; p2 = pi; while (ml != NULL)
{ tl = ml->ops; while (tl != NULL)
{ p2->mid = ml->mid; p2->qeme_no = tl- >qeme_no ; cnt++ ,- p2 ++; tl = tl->next;
} ml = ml->next;
}
MQEMT- >ptl_ptr = pi; MQEMT- >num_pts = cnt;
void Conv to MTlistO
{ lpPTLIST pi; lpMTLIST ml; lpTLIST tl; MID tmid; int cnt ,-
Pending_TXNs = NULL; pi = MQEMT->ptl_ptr; cnt = 1 ; while (cnt <= MQEMT- >num_pts)
{ tmid = pl->mid;
Add_MTlist (&Pending_TXNs, £iml,pl->mid) ; tl = ml->ops; while ( (cnt <= MQEMT- >num_pts) &&
(pl->mid.host == tmid. host) && (pl->mid.tid == tmid. tid))
{ AddJTlist (&tl,pl->qeme_no) ; pl++; cnt++;
} ml->ops = tl;
} PendingJTXNs = ml;
void Add_Tlist ( lpTLIST *head, int qeme_no) lpTLIST curr, prev,- lpTLIST new; new = (TLIST *) malloc (sizeof (TLIST) ) ; new->qeme_no = qeme_no; new->next = NULL; curr = *head; prev = curr,- while (curr != NULL)
{ prev = curr,- curr = curr->next;
if (prev == NULL) *head = new; else prev->next = new;
void Add_MTlist ( lpMTLIST *head, lpMTLIST *tail, MID mid)
{ lpMTLIST curr, prev; lpMTLIST new; new = (MTLIST *) malloc (sizeof (MTLIST) new->mid = mid; new->ops = NULL; new->next = NULL; *tail = new; curr = head; prev = curr; while (curr != NULL)
{ prev = curr,- curr = curr->next;
if (prev == NULL) head = new; else prev->next = new;
}
BOOL Find_MTlist ( lpMTLIST head, lpMTLIST *pres, MID mid) lpMTLIST curr; int found = 0 ,- curr = head; while ((curr != NULL) && Ifound)
{ if ( (curr- >mid. host == mid. host) && (curr->mid. tid == mid. tid)) found = 1 ,- else curr = curr->next;
} if (found)
{ pres = curr,- return (TRUE) ;
} else
(
♦pres = NULL; retur (FALSE) ; }
BOOL FindJTlist ( lpTLIST head, int qeme no)
{ lpTLIST curr; int found = 0 ; curr = head; while ((curr != NULL) && Ifound)
{ if (curr->qeme_no == qeme_no) found = 1 ,- else curr = curr->next; } if (found) return (TRUE) ; else return (FALSE) ,-
void Del_MTlist_All ( lpMTLIST *head)
{ lpMTLIST curr, prev; BOOL Return_Status; curr = head; head = NULL; while ( curr ! = NULL)
{ prev = curr,- curr = curr->next ,- prev->next = NULL;
Del_Tlist (&prev->ops) ,- free (prev) ; if (Return_Status == FALSE)
DiagC'Del MTlist All: Problem with freeing memory."); }
BOOL Del_MTlist ( lpMTLIST ♦head, MID mid)
{ lpMTLIST curr, prev; int found = 0 ; BOOL ReturnjStatus; curr = head; prev = curr ,- while ((curr != NULL) && Ifound)
{ if ( (curr- >mid. host == mid. host) && (curr- >mid. tid == mid. tid)) found = 1 ; else
{ prev = curr,- curr = curr->next;
if (found)
{ DelJTlist (&curr->ops) ,- if (curr == prev) head = curr->next; else if (curr->next == NULL) prev->next = NULL; else prev->next = curr->next; curr->next = NULL; free (curr) ; if (Return_Status == FALSE)
Diag ( "Del_MTlist : Problem with freeing memory...") return (TRUE) ,-
} else return (FALSE) ;
void DelJTlist ( lpTLIST head)
{ lpTLIST curr, rev; BOOL Return_Status ,- curr = head; while (curr != NULL)
{ prev = curr; curr = curr->next; prev->next = NULL; free (prev) ; if (Return_Status == FALSE)
Diag( "Del_Tlist : Problem with freeing memory.
♦head = NULL;
void Sub_Addr ( LONG diff, BLAD *x, BLAD y)
{
♦diff = (LONG) ( ( (y->segment-x->segment) SEGMENT_SIZE) +
QEMT_Size+ (y- >block-x->block) *BLOCK) ;
void Conv_Addr ( LONG diff, BLAD ♦x)
{
♦diff = (LONG) ( (x->segment^SEGMENT_SIZE)+QEMT_Size+(x->blockiBLOCK) ) ;
}
int GenjQEM_Seq_No ( IpSN tSeq No)
{ long temp;
// Generate unique QEMT sequence // number based on system time // and unique counter. temp = time (&tSeq_No->timestamp) ; tSeq_No->counter = QEMT_Seq_No++; return (QSUCCESS) ;
int Gen_LREC_Seq_No ( IpSN tSeqJSTo) long temp ;
// Generate unique LREC sequence // number based on date and time. temp = time (&tSeq_No->timestamp) ; tSeq_No->counter = LREC_Seq_No++ ,-
return (QSUCCESS)
int Gen_QEME_TS ( unsigned long *tSeq No)
{
// Generate unique QEMT sequence // number based on date and time.
*tSeq_No = QEMEJTS++ ; return (QSUCCESS) ,-
BOOL Bigger_Seq_No ( IpSN seq_nol , IpSN seq_no2) if ( (seq_nol->timestamp > seq_no2->timestamp) | |
( (seq_nol->timestamp == seq_no2->timestamp) && (seq_nol->counter > seq_no2->counter) ) ) return (TRUE) ,- else return (FALSE) ; /*
* *
♦♦ Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
♦♦ UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
♦♦ IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
♦♦ OR DISCLOSURE.
**
* THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
♦♦ TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
♦ OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
♦♦ OpenMQ
♦♦ Module: qnetd.c
♦♦ Author: Derek Schwenke 9/8/95
* *
*/ ttinclude "qlib.h" ttinclude "qnetd.h"
// This thread listens on each Buffer that QNETD owns. // Resurve a buffer // Wait For READY // Read the message void QnetdAdminRequest (IpSMBUF buf) { char +p = buf->mdata; int i; switch (buf->msgh. sub_mode) { case QNETD_TRAN_INQ : buf ->msgh. sub_mode = ResolveTran (&buf ->msgh .mid) ; break; case QNETD_RT_BROADCAST :
Warn ( "QnetdAdminReques : RT Broadcast not implemented"); break ,- case QNETD_BUF_STATUS : sprintf (p, "QNETD status for %p\n" , SHAREDATA (hos ip) ) ; p = p + strlen(p); for(i=0;i<SHAREDATA(nsbuf) ;i++) {
IpSMBUF b = SMBUFADDR(i) ; sprintf (p, "%d: %d %s\n" , i , b->status, b->name) ; p = p + strlen(p); break ,- default: Warn ( "QnetdAdminRequest : undefined sub_type of request (%d)", buf - >msgh . sub__mode) ;
DWORD ListenSMBuff () {
IpSMBUF buf ; int stat ,pass, bnum, rtn;
SMOBJS sync ; ttdefine MAXPASS 1 /* 1 Attempt to send on the socket / Sleep (1000) ; // Wait for others to init, no real reason
// Reserve a buffer
Diag ( "ListenSMBuff [-] : Calling ReserveSharedBuffer") ; bnum = ReserveSharedBuffer (0, "QNETD" , SMBUFJEMPTY, &sync) ; buf = SMBUFADDR(bnum) ;
while (1) { stat = 0; // Wait for a message
Diag ( "ListenSMBuff [%d] : Waiting for buffer ready" , bnum) ,- if ( (rtn = WaitForSingleObject (sync. readyh, INFINITE) ) == WAITJFAILED )
Fail ( "ListenSMBuff [%d] : Failed while waiting for the buffer ready %d #%
// Sanity check the buffer if (buf->status != SMBUF_SEND_MESS) {
Warn ( "ListenSMBuff [%d] : Buffer status was wrong I %d" , bnum, buf->status) ; }
// Read the message
Diag ( "ListenSMBuff [%d] : got:%s", bnum, buf - >mdata) ,- pass = 0 ,- if (SHAREDATA (hostip) != buf - >msgh . to_node) { // Not local while (pass++ < MAXPASS ) { // Make N trys to send the message if (SendRemoteMess (buf , 0) ) { if (buf ->msgh. mode != ADMINREQ_MODE) // Admin req's may fail Warn ( "ListenSMBuff [%d] : SendRemoteMess failed" , bnum) ; } else {
// send was ok now wait for the ACK/NACK if ((rtn = WaitForSingleObjec (sync. ackh, 22000) ) == WAITJOBJECTJ0 if (bu ->msgh. mode == NACK_MODE) pass = 100;
Diag ( "ListenSMBuff (%d] : got an ack/nack" , bnum) ,- break ,- } else if (rtn == WAITJTIMEOUT) {
Warn ( "ListenSMBuff [%d] : No ack Timed out after 22 sec", bnum, rt } else {
Warn ( "ListenSMBuff [%d] : No ack WaitForSingleObject=%d" ,bnum, rt
else { // Local message for QNETD Say (" ListenSMBuff [%d] : GOT LOCAL MESSAGE" , bnum) ; if (buf->msgh.mode == ADMINREQ_MODE) {
QnetdAdminReques (buf ) ; } else {
Warn ( "ListenSMBuff [%d] : Qnetd drops non-admin request" , bnum) pass = MAXPASS + 2 ;
if (pass < MAXPASS + 1) buf->status = SMBUF_RETURN__MESS ; else buf->status = SMBUFJRETURNJFAIL;
// Notify the sender "Your message was read"
Diag ( "ListenSMBuff [%d] : releases DONE status = %d" , bnum, buf ->status) if ( I ReleaseSemaphore (sync .doneh, 1,0))
Warn ( "ListenSMBuf f [%d] : ReleaseSemaphore done #%d" , bnum, GetLastError ( ) } //loop
Say ( "ListenSMBuf f [%d] Aborts" ,bnum) ; return (0) ;
'///////Ill/Ill///// II
/I Common routines and definitions used by OpenMQ
//
///////////////////////////////////////////////////////////////////////////// < ttinclude "qlib.h" ttinclude "qnetd.h"
// Routines 111 / 11111111111111 II 11111111111111111111111111 / 1 II 1111111111111 //// /
void ReadParms (int *nsbuf) { // ♦nsbuf is Optional char line[LINESIZE] ; char parm [LINESIZE] ,- char value [LINESIZE] ; FILE *fp = fopen(PARMNAME, "r") ;
if (sm_base) { // If we have shared memory, then set defaults.
SHAREDATA (diag) = 1 ;
SHAREDATA (time out) = 20000; } if ( I fp )
Fail ("Cant open the parameters file %s " , PARMNAME) ,- while (fgets (line, LINESIZE, fp) ) { ♦parm = *value = 0; if ( 2 != sscanf (line, "%s = %s" , parm, value) ) { parm = 0 ;
} else if ( I strcmp (parm, "nsbuf ") ) { if (nsbuf) { sscanf (value, "%d" , nsbuf) ; if (♦nsbuf > MAXNSMBUF) {
Warn ("parameter: nsbuf %d exceeds %s maximum" , nsbuf ,MAXNS ♦nsbuf = MAXNSMBUF;
} else if (sm_base && I strcmp (parm, "diag" ) ) { sscanf (value, "%hd" , &SHAREDATA(diag) ) ,-
} else if (sm_base && I strcmp (parm, "time_out" ) ) { sscanf (value, " d" , &SHAREDATA(time_out) ) ;
} else if (sm_base) {
Say ("ReadParms: Ignoring: %s",line);
if (ferro (fp) ) {
Fail ("read error in parameters file %s" , PARMNAME) ; clearerr (fp) ,- f close (fp) ; /*
**
** Copyrigh (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
* * UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT ** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE ** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
* * OR DISCLOSURE. ** ** THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
* * TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
* * OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* * EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA. ** ** OpenMQ ** Module: qnetd.c
* * Author: Derek Schwenke 9/8/95 **
*/ ttinclude "qlib.h" ttinclude "qnetd.h" ttinclude "rt.h" main (int argc, char ♦♦argv) { HANDLE hSMT, hTCPT, hDOG; DWORD idSMT,idTCPT, idDOG; WSADATA WSAData; int nsbuf = 0 ;
// DLL Init if (WSAStartup (0x0101, kWSAData) ) Fail ( "WSAStartup ( ) f iled" ) ;
// Read only nsbuf. ReadParms (&nsbuf) ,-
SharedMemlnit (nsbuf) ;
// Read and set all other shared memory parameters ReadParms (0) ;
// Load routing table into shared memory ReadRT ( ) ,-
// Create Threads - listen for connections from other qnetd's //AfxBeginThread?? hSMT = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) ListenConn, 0,0,&idTCPT // Create Threads - listen for shared memory buffer requests hTCPT = CreateThread (NULL, 0 , (LPTHREAD_START_ROUTINE) ListenSMBuff ,0,0, &idSMT) // Create Background watchdog thread hDOG = CreateThread (NULL, 0, (LPTHREADjSTARTJROUTINE) WatchDog, 0, 0, kidDOG) ;
Sleep(2000); AskC'QNETD All Done?") return (0) ,- /* * *
** Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
** OR DISCLOSURE.
**
*♦ THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
♦♦ TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
♦♦ OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
* OpenMQ
*♦ Module: routab.c
** Author: Derek Schwenke 9/8/95
**
♦♦ Routing table funtions */
ttinclude "qlib.h" ttinclude "qnetd.h" ttinclude "rt.h" ttinclude <string.h> ttinclude <ctype.h>
/* int Str2Port (char ♦str) { int port=0; if (sscanf (str, "%♦ [~\[] [%d",&port))
Say("Str2Port %s returns %d" , str, port) ; else
Say("Str2Port %s FAILED" , str) ; return (port) ;
}
*/
// Routing table entry, , , to be deleted t
Figure imgf000139_0001
static int is_ip(char s) { return ( isdigit ( s [0] ) ) ,- . } static int is_stype ( char ♦s ) { return ( strlen ( s ) > 3 && strstr ( &CLASSNAMES , s ) ) ; }
// The table looks like this :
//137 . 203 . 1 . 1 mars NT3 . 5 Server [100]
// classO router c : /q/route -master
// classl QS1 [Q1 , Q2 , Q3 ] c : /q/qserv -threads 66 -more opts
//
// The node line is:
// IP# node_name node_type Client_or_server [QNETD address] Preferred_servers, , ,
// The Services lines is:
// type physical_name [logidal_names, , , ] path_to_executable options int parseRTnode ( char line, int line_no, int ^ip, char node, char ntype, char cs, int *port, char servers) { char ip_str [NAMESIZE] ; char cs_str [LINESIZE] ,- strcpy (servers ,","); if ( 4 > sscanf (line, "%s %s %s %s %s" , ip_str, node, ntype, cs_str, ^servers [1] Fail ( "Routing Table Line %d is not complete: %s" , line_no, line) ,- if (strlen (servers) > 1) strcat (servers ,","); else strcpy ( servers , " " ) ; if (!(*ip = Str2IP(ip_str) ) )
Fail ("Routing Table Line %d ip does not scan: %s" , line_no, line) ,- if (2 != sscanf (cs_str, "%[Λ\ [] [%d] ",cs, port) )
Fail ("Routing Table Line %d QNETD client/server does not scan: %s",line_no return (1) ;
} int parseRTservices (char line, int line_no, char *clas, char *physical_name, char ♦logical_names, char *path, char *opts) { char services [LINESIZE] ; int len; strcpy (opts , " " ) ; if ( 3 > sscanf (line, "%s %s %s %["]" ,clas, services, path, opts) )
Fail ("Routing Table: line %d is not complete: %s" , line_no, line) ,- strcpy (logical_names, ", ") ; sscanf (services, "% [~\ [] [%s] " , physical_name, &logical_names [1] ) if((len = strlen (logical_names) ) < 2) // No logical name sprintf (logical_names, ",%s, " ,physical_name) ; else logical_names [--len] = ', '; return (1) ;
}
/* + +
**char * NewStr(char * s) {
** char * n = malloc (strlen (s) +1) ;
** if (In) FailC'Malloc error in NewStr"),-
*♦ return (strcpy (n, s) ) ;
** ]
**
* *
♦♦void FreeNcopy (char * o, char ♦ s) {
** char n = malloc (strlen (s) +1) ;
♦♦ if (In) FailC'Malloc error in FreeNcopy"),-
** strcpy (n, s) ,-
* free (*o) ,-
*♦ ♦o = n,-
** ]
**
*/
void SwapRTdpRT RT1, lpRT RT2) { lpRT P,R,PRT1=0,PRT2=0;
Diag("SwapRT(%s,%s) " , RT_NODE (RT1) , RT_NODE (RT2 ) ) ; if (RT1 == RT2) return;
// Scan for the prel and pre2 nodes
P = RTROOT; while (R = NextRT(P)) { // Find both the previous nodes if (R == RT1) PRT1 = P; if (R == RT2) PRT2 = P;
P = R;
} if (!(PRT1 && PRT2)) return;
// Swap pointers
PRTl->next_offset = RT2C(RT2) - RT2C(PRT1); if (RT2->next_offset) PRT2 - >next_offset = RT2C (RT_NEXT (RT2) ) - RT2C(PRT2); else PRT2->next_offset = 0 ,-
RT2->next_offset = RT2C(RT1) - RT2C(RT2);
} int fgetshfchar *line,int max, HANDLE rth) { // Aproximate fgetsO
// Read 1 char at a time until \n int rd=l,rdn=0; while ((rdn < max-1) && ReadFile (rth, line, 1, &rd, 0) ) { if (rd != 1) break; // Did not get one byte if (*line == '\n') break; 1ine++ ; rdn++ ; } if (*line = ' \n' ) line- if (rd) line++; *line = 0; return (rdn) ;
HANDLE MakeRoutingTableO { // Only be called by QNETD. int i,line_no = 0 ,- PIN_ADDR pia; char line [LINESIZE] ;
HANDLE rth = CreateFile ( ROUTNAME ,
GENERIC_WRITE, // GENERIC_READ
FILE_SHARE_WRITE, 0, // FILE SHARE READ OPEN_ALWAYS , FILE ATTRIBUTE NORMAL, 0) ;
sprintf (line, "RTJVERSION l\r\n") ; WriteFile (rth, line, lstrlen (line) , &i, 0) ; sprintf (line, "#### Servers\r\n" ) ; WriteFile (rth, line, lstrlen (line) , &i,0) ;
i = htonl ( (u_long) SHAREDATA (hostip) ) ,- // Back to network format pia = (PIN_ADDR) (&i) ; sprintf (line, "%s %-16s Win Server [4011] \r\n" , inet_ntoa ( ♦pia^
WriteFile (rth, line, lstrlen (line) , &i, 0) ,- sprintf (line, "tt classl QS1 [QS1] c : \\q\\bin\\ramq -options\r\
WriteFile (rth, line, strlen (line) , &i,0) ,- sprintf (line, "#### Clients\r\n" ) ,- WriteFile (rth, line, lstrle (line) , &i, 0) ;
CloseHandle (rth) ; rth = CreateFile ( ROUTNAME , GENERIC_RE D, FILE_SHARE_READ, 0, OPENJEXISTING, FILE_ATTRIBUTE_NORMAL, 0) ; if (rth == INVALID_HANDLE_VALUE )
FailC'Cant create the default routing table file %s" , &ROUTNAME) ; return (rth) ,-
void ReadRTO { // Only be called by QNETD. int line_no = 0; char line [LINESIZE] ; char first [LINESIZE] ; _ . ,Λ char preferred [LINESIZE] ,-
// must be read | rite so that on second open we dont fail. HANDLE rth = CreateFile ( ROUTNAME ,
GENERIC_WRITE|GENERIC_READ, // not
FILE_SHARE_WRITE|FILE_SHARE_READ, 0, // not
OPEN_EXISTING, // not OPEN_ALWAYS
FILE_ATTRIBUTE_NORMAL, 0) ; RTE rte; // Current RTE lpRT rt,rts; char *cp;
SHAREDATA (rt_ver) = 0 ,- if (SHAREDATA (rt_pingpong) ) // Not the active RT rts = rt = (lpRT) sm_base->RT [0] ; else rts = rt = (lpRT) sm_base->RT [1] ;
memset (rt, 0,MAXRTSIZE) ,- // Clear routing table (not required) cp = rt->s + 1; // 1st node is always nop rt->ntype_index = cp++ - (char *) rt->s; // 1st node is always nop rt->apps_index = cp++ - (char ) rt->s; // 1st node is always nop strcpy (preferred, " " ) ; if (rth == INVALID_HANDLE_VALUE ) { // No routing table existed so makeon rth = MakeRoutingTable () ;
} while (fgetsh(line,LINESIZE-l,rth) ) { line_no++ ; sscanf (line, "%s" , first) ,- if (first == '#') { line_no = line no, } else if (is_ip (first) ) { // New node //
// Perhaps we can filter other clinets out here to save space // parseRTnode (line, line_no, &rte. ip, rte. node, rte . ntype , rte . cs , &rte . qnetd_port , rte . servers) ,-
// Start a new node in the RT RT_NOFFSET(rt) = ++cp - RT2C(rt); rt = NextRT (rt) ; // Build RT in shared memory
RT_IP(rt) = rte.ip; // IP number
RT_PORT(rt) = rte . qnetd_port ; // Port number
RT_NOFFSET(rt) = 0; // End of the chain strcpy (RT_N0DE(rt) , rte. node) ; // Node string rt->ntype_index = strlen (RT_N0DE (rt) ) + 1; strcpy (RTJNTYPE(rt) , rte. ntype) ; rt->apps_index = strlen (RT_NTYPE (rt) ) + 1 + rt->ntype_index; cp = RT_APPS(rt) ;
*cp = 0;
if ( I strcm (SHAREDATA (hostname) ,RT_NODE(rt) ) ) { strcpy (preferred, rte. servers) ; SHAREDATA ( ostip) = RTJIP(rt);
DiagC'ParseRT this node is %s ip=%p" , SHAREDATA (hostname) , SHAREDATA (h
} else if (is_stype (first) ) { // New service // parseRTservices (line, line_no, rte. serv_class, rte . physical , rte . logicals , rte .serv_path, rte. serv_opts) ; // format: [QS1] , Ql, Q2 , [QS2] , Q4 , sprintf (cp, " [%s] %s" , rte. physical, rte . logicals) ; cp = strchr (cp, 0) ; // Advance the pointer
} else if ( I strcmp (first , "RTJVERSION" ) ) { sscanf (line, "%^s %d" , &SHAREDATA (rt ver) ) ,- }
// if (terror (rth) ) {
// FailC'ParseRT read error on %s . \n" , &ROUTNAME) ,-
// clearerr (rth) ,-
// }
CloseHandle (rth) ;
// Sort this list according to the preferred servers PrintRT(rts, "Before sorting") ,- if (strlen (preferred) > 2) { lpRT rtf,rtp = NextRT(rts) ,- char *e,+p = preferred + 1 ,-
Diag ( "ReadRT: Sorting preferred servers : %s" , preferred) ; // Swap entries to achive the right order while (rtp && ((strlen(p) > 2) ) ) { if (e = strchr (p, ',') ) *e = 0; rtf = rts; while (rtf = NextRT(rtf)) if ( I strcmp (RT_NODE (rtf ), p) ) break; if (Irtf) {
SayC'ReadRT: Cant find preferred server %s",p); break;
}
SwapRT(rtp,rtf) ; rtp = NextRT(rtp) ; if (e) p = e + 1; else break;
}
PrintRT (rts, "After sorting");
}
// Ping Pong the RT tables, make this one active if (SHAREDATA (rt_pingpong) )
SHAREDATA (rt_pingpong) = 0; else
SHAREDATA (rt_pingpong) = 1; SHAREDAT (rt_rev) ++; // Every handle will re-load from new RT.
// We must find some way to set the IP addr, and the RT is the only way to if ( I SHAREDATA (hostip) )
WarnC'ReadRT: could not find host %s in the file %s" , SHAREDATA (hostname), & //{ {NOJDEPENDENCIES} }
// Microsoft Visual C++ generated include file.
// Used by qnetd.rc
// ttdefine ICON1 2
// Next default values for new objects
// ttifdef APSTUDIO_INVOKED ttifndef APSTUDIO_READONLY_SYMBOLS ttdefine _APS_NEXT_RESOURCE_VALUE 102 ttdefine _APS_NEXT_COMMAND_VALUE 40001 ttdefine _APS_NEXT_CONTROL_VALUE 1000 ttdefine _APS_NEXT_SYMED_VALUE 101 ttendif ttendif
/* **
** Copyrigh (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
** OR DISCLOSURE.
**
** THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
** TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
** OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
** OpenMQ
** Module : shm_init . c
** Author : Derek Schwenke 9/8/95
**
*/ ttinclude "qlib . h"
// Global data - for qnetd only
// QNETD keeps an open handle for each sync object so that they are // never deleted by the OS, until QNETD exits, then all bets are off. // QNETD will not call CloseHandle ( ) so they will stay active.
// static int sharmeminit_done = 0; // sharmeminit done flag. static HANDLE SMT; // Handle for access to SM table.
SMOBJS SYNC [MAXNSMBUF] ; // Handles for all sync objects
// ShareMemlnit should be called once only once by QNETD.
LPVOID SharedMemlnit (int nsbuf) {
HANDLE hMap; // Shared memory mapping
IpSMBUFH lpBUFH; // Pointer to base of shared Memory
PHOSTENT lpent ; int i, sm_size,CFM_error; char * c;
//Say ("SharedMemlnit: starts %d buffers. ", nsbuf) ; if ( 0 ) { // must think of a better test... see if shared mem aleady exists // a lock would just say if another qnet had the shared mem. not anything abo
Warn ("ShareMemlnit was already done!!!!"); } else { if (Insbuf) FailC'nsbuf can not be '0' ");
// Make QopenO lock if (I CreateMutex ( NULL, FALSE, MUTQOPEN ))
Fail ("ShareMemlnit cant create mutex %s" , &MUTQOPEN) ;
// Make shared memory update lock if (I (SMT = CreateMutex (NULL, TRUE, SMEMTABLE) ) )
Fail ("ShareMemlnit cant create mutex %s" , &SMEMTABLE) ;
// Calculate the size of shared memory sm size = MAXSMSIZE (nsbuf) ; //Say ("Shared memory will be %d bytes\n" , sm_size) ;
// Create the shared memory hMap = CreateFileMapping (
(HANDLE) OxFFFFFFFF, // Do not use a real disk file NULL, // No security
PAGEJREADWRITE, // Page protection 0, sm_size, // File size SMEMNAME) ; // Name
CFM_error = GetLastError () ; if ( I hMap )
Fail ( "CreateFileMapping returned null");
// Map the shared memory into my address space lpBUFH = sm_base = MapViewOfFile ( hMap, // object HANDLE
FILE_MAP_WRITE, // Access 0,0, // Address into the file
0 ) ; // Size (Full file) if ( I smjbase )
Fail ("MapViewOfFile returned null");
if (CFM_error == ERROR_ALREADY_EXISTS) { Fail ("Shared memory already in use . " ) ;
// Code should also check clcok to see if QNET is running
ForcedBufferReset (i, 0, 0) ,- for (i = 0 ; i < nsbuf ; i++ ) {
ForcedBufferReset (i,0, 0) ;
} else {
// Initialize the buffers data for (i = 0 ; i < nsbuf ; i++ ) {
IpSMBUF b = SMBUFADDR(i) ; strcpy (b->name, "empty") ; b->status = SMBUF_EMPTY; b->sub status = 0;
, » "
// Create all syncronization objects free, ready, done, for (i = 0 ; i < nsbuf ; i++ ) { char freename [NAMESIZE] , readyname [NAMESIZE] , donename [NAMESIZE] , ackna sprintf (freename, MUTFREFMT, i) ; sprintf ( readyname , SEMRDYFMT , i) ; sprintf (donename, SEMDONFMT, i) ; sprintf (ackname , SEMACKFMT , i ) ; // sync QNETD tcp lister with buffer list if ( I (SYNC[i] .freeh = CreateMutex (NULL, FALSE, freename) ) )
Fail ("Cant create mutex %s", freename) ; if ( ! (SYNC [i] .readyh = CreateSemaphore (NULL, 0, 1, readyname) ) )
Fail ("Cant create semaphore %s", readyname) ; if ( ! (SYNC [i] .doneh = CreateSemaphore (NULL, 0, 1, donename) ) )
Fail ("Cant create semaphore %s" , donename) ; if ( ! (SYNC[i] .ackh = CreateSemaphore (NULL, 0,1, ackname) ) )
Fail ("Cant create semaphore %s" , ackname) ; }
// Get this host name if (gethostname (SHAREDATA (hostname) , sizeof (SHAREDATA (hostname) )) )
Warn ( "ReadParms: gethostname failed WSAGetLastError 0 =%d" ,WSAGetLast
// Get host ip from the hostent table if (Idpent = gethostbyname (SHAREDATA (hostname) ) ) )
Warn ("ReadParms: gethostbyname failed WSAGetLastError () =%d" ,WSAGetLastE i = *((int*) lpent->h_addr) ; SHAREDATA (hostip) = htonl(i);
// Get rid of the domain extention "bob.meitca.com" if (strchr (SHAREDAT (hostname) ,'.')) {
Say ("Truncating host name %s" , SHAREDATA (hostname)) ,-
strchr (SHAREDATA (hostname) , ' . ' ) = 0; }
SHAREDATA (nsbuf) = nsbuf; ReleaseMutex (SMT) ;
//Say ( "ShareMemlnit returns %d bytes at %p" ,sm_size, smjbase) return (sm base) ;
User: root Host : bunny Class : bunny Job: stdin
/* **
** Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
** OR DISCLOSURE.
**
** THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
** TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
** OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
** OpenMQ
** Module : tcp . c
** Author: Derek Schwenke 9/8/95
**
*/ ttinclude "qlib.h" ttinclude "qnetd.h" ttinclude "rt.h" ttinclude "netadmin.h" extern SMOBJS SYNC [MAXNSMBUF]
int SAY_WSAERROR_TEXT ( ) { int re = WSAGetLastError () ; ttdefine ERROR_BUF_LEN (1000) char pszError [ERROR_BUF_LEN] ; wsprintf (pszError, "WinSock error re) switch (re)
{ case WSAEINTR: lstrca (pszError, Interrupted system call"),- break; case WSAEBADF : lstrcat (pszError, Bad file number"),- break; case WSAEACCES lstrcat (pszError, Permission denied"); break; case WSAEFAULT lstrcat (pszError, Bad address") ; break; case WSAEINVAL lstrcat (pszError, Invalid argument"); break; case WSAEMFILE lstrcat (pszError, Too many open files"); break; case WSAEWOULDBLOCK: lstrcat (pszError, Operation would block") ; break; case WSAEINPROGRESS : lstrcat (pszError, Operation now in progress"); break case WSAEALREADY : lstrca (pszError, Operation already in progress"); b case WSAENOTSOCK: lstrcat (pszError, Socket operation on non-socket") ; case WSAEDESTADDRREQ : lstrcat (pszError, Destination address required"); br case WSAEMSGSIZE: lstrcat (pszError, Message too long"); break; case WSAEPROTOTYPE : lstrcat (pszError, Protocol wrong type for socket"); case WSAENOPROTOOPT : lstrcat (pszError, Protocol not available"),- break; case WS EPROTONOSUPPORT lstrcat (pszError "Protocol not supported"),- break; case WSAESOCKTNOSUPPORT : lstrcat (pszError "Socket type not supported"); bre case WSAEOPNOTSUPP : lstrcat (pszError, Operation not supported on socket" case WSAEPFNOSUPPORT : lstrcat (pszError, Protocol family not supported"),- b case WSAEAFNOSUPPORT : lstrcat (pszError, Address family not supported by pr case WSAEADDRINUSE : lstrcat (pszError, Address already in use") ; break; case WSAEADDRNOTAVAIL : lstrcat (pszError, Can't assign requested address"); case WSAENETDOW : lstrcat (pszError, Network is down"); break; , case WSAENETUNREACH : lstrca (pszError, Network is unreachable"); break;.„--' case WSAENETRESET : lstrcat (pszError, Network dropped connection on rese case WSAECONNABORTED : lstrcat (pszError, Software caused connection abort " ) case WSAECONNRESET : lstrcat (pszError, Connection reset by peer"); break; case WSAENOBUFS : lstrcat (pszError, "No buffer space available"); break case WSAEISCONN: lstrcat (pszError, "Socket is already connected"); bre case WSAENOTCONN : lstrcat (pszError, "Socket is not connected") ; break; case WSAESHUTDOW : lstrca (pszError, "Can't send after socket shutdown") case WSAETOOMANYREPS lstrca (pszError, "Too many references: can't spli "^ case WSAETIMEDOUT : lstrcat (pszError, "Connection timed out"); break; case WSAECONNREFUSED lstrcat (pszError, "Connection refused"); break; case WSAELOOP : lstrcat (pszError, "Too many levels of symbolic links" case WSAENAMETOOLONG lstrcat (pszError, "File name too long"); break;. case WSAEHOSTDOWN : lstrcat (pszError, "Host is down"); break; case WSAEHOSTUNREACH lstrcat (pszError, "No route to host"); break; case WSAENOTEMPTY: lstrcat (pszError, "Directory not empty"); break; case WSAEPROCLI : lstrcat (pszError, "Too many processes"); break; case WSAEUSERS lstrcat (pszError, "Too many users"); break; case WSAEDQUOT lstrcat (pszError, "Disc quota exceeded"),- break; case WSAESTALE lstrcat (pszError, "Stale NFS file handle"),- break; case WSAEREMOTE : lstrcat (pszError, "Too many levels of remote in path" case WSASYSNOTREADY lstrcat (pszError, "Network sub-system is unusable"); case WSAVERNOTSUPPORTED : lstrcat (pszError, "WinSock DLL cannot support this case WSANOTINITIALISED lstrcat (pszError, "WinSock not initialized"); break; case WSAHOST_NOT_FOUND : lstrca (pszError, "Host not found"); break; case WSATRY_AGAIN : lstrcat (pszError, "Non-authoritative host not found") case WSANO_RECOVERY : lstrcat (pszError, "Non-recoverable error"); break; case WSANO_DATA: lstrca (pszError, "Valid name, no data record of requ ttifdef WIN32 case WSAEDISCON: lstrca (pszError, "Disconnect"),- break; ttendif default : lstrcpy (pszError, "Unknown WinSock error") ,- break;
}
Say (pszError) ,- re urn (re) ; }
IpST STroot = NULL;
IpST FindSocket (int ip) { IpST stp = STroot; while (stp) { if (stp->ip == ip) break; stp = stp->next;
if (stp == NULL)
Say ("FindSocket: ip=%p not found. " , ip) ; else
Diag ( "FindSocket : ip=%p found. " , ip) ; return (stp) ;
} int RemoveSocket (SOCKET s) { // This needs to be thread safe IpST stp = STroot; // Needs to kill the thread listening on this s IpST stpp = NULL; while (stp) { if (stp->s == s) break; stpp = stp; stp = stp- >next ; } if (stp) {
DiagC'RemoveSocket: closesocket () ip=%p" , stp->ip) ; closesocke (s) ; if (stpp) stpp->next = stp->next; else
STroot = stp->next; free (stp) ; return (1) ,- } else if ( (int) s )
Warn ( "RemoveSocket : s=%p NOT FOUND! I " , s) ; return (0) ;
DWORD ListenOnConn pST stab) { SOCKET s = stab->s; int ip = stab->ip; int port = stab->port;
SMBUF buf; // Buffer where messages will be held IpSMBUF abuf; // Buffer where ack data will be copied int re; // recv code int i,bnum; // Buffer number to send ack QHANDLE q,- // Psudo handle used to forward messages memse (&q, 0, sizeof (QHANDLE) ) ;
DiagC'ListenOnConn: PARAMETERS socket=%d ip=%s port=%d" , s, IP2Name dp) ,port
Diag("ListenOnConn(%s:%d) : Waiting for some data" , IP2Name dp) , s) ; whileUrc = recv (s, (char *) &buf .msgh.MAXTXSIZE, 0) ) > 0) {
SHAREDAT (stat .rx) ++; // Any communication received statistics
if (re == SOCKET_ERROR) {
Warn("ListenOnConn(%s:%d) : ends with SOCKET_ERROR=%d" , IP2Name (ip) , s,SAY break; if (re < sizeof (MSGH) ) { // Safty check Warn("ListenOnConn(%s:%d) : Dropping too small message" , IP2Name (ip) , s) ; continue; if (buf .msgh. size > MAXMSGDATA) { Warn("ListenOnConn(%s:%d) : message %d:%d with too big size %d bytes",
IP2Name (ip) , s, buf .msgh.mode, buf .msgh. subjmode, buf .msgh. size) ; // continue;
Diag("ListenθnConn(%x:%d) : Mode=%d:%d flag=%x %d bytes : %s" , IP2Name dp) ,s, buf .msgh.mode, buf .msgh. sub_mode, buf .msgh. flags , re , buf .mdata) ; switch(buf .msgh.mode) { case PUT_MODE: case REQUEST_MODE: case COMMIT_MODE: case ABORT_MODE: case ADMINREQ_MODE :
// This could be optimized but for now:
// (1) Fake a que handle
// (2) Put data to the fake que
// If the previous q handle was not for this server, fake the queue han if (0 == strcmp (buf .msgh. to_server, "")) { // No server name (see the rep IpSMBUF b = SMBUFADDR (buf .msgh. to_smbuf) ; if (strcmp (b->name, "empty" ) ) strcpy (buf .msgh. to__server, b->name) ,- else
Warn ( "ListenOnConn (%s : %d) : msg to 'empty' buffer %d" , IP2Name (ip) ,
if (strcmp (q. msgh. to_server, buf .msgh. to_server) ) { //Construct que handle from messge header memcpy (kq.msgh, &buf .msgh, sizeof (MSGH) ) ,- - q.base_flags = 0; q.time_out = SHAREDATA ( time_out ) ; if ( IFindSMBuffers (&q,buf .msgh. to_node,buf .msgh. to_server, -1) ) {
Warn ( "ListenOnConn (%s :%d) : ERROR No local buffers found for %s",I strcpy (q. msgh. to_server, "") ,- // So next time you remake the que buf . msgh. to_node = ip; // send back to orign buf .msgh . to_port = port; // send back to orign (port not used) buf .msgh. mode = NACK_MODE; // Perhaps QsarO will set buf. msgh ' t Diag ( "ListenOnConn (%s : %d) : Sending NACK to %p [%s] " , IP2Name p ) if (SendRemoteMess (Sbuf, 0) )
Warn ( "ListenOnConn (%s :%d) : Could not SendRemoteMess (NACK) ", IP2 continue ;
} else { // re-use the existing handle, but update the message header Diag ( "ListenOnConn (%s : %d) : Reusing handle for %s" , IP2Name dp) , s, buf . memcpy (kq.msgh, Sbuf .msgh, sizeof (MSGH) ) ,- //q. msgh. mode = buf . msgh . mode ; // QsarO uses q. msgh. mode. Set recei
} if (buf .msgh. flags & Q_FAILOVER) // No Failover please buf .msgh. flags = buf .msgh. flags & ( !Q_FAILOVER) ; // Put data into the local que and get any answer
Diag ( "ListenOnConn (%s : %d) : Before QsarO MODE=%d " , IP2Name (ip) , s, q.msgh
// Last change: added last parameter of QsarO the gotten mess header with if (QSUCCESS != QsendAndReceive (&q, 0 , 0 , /*buf .msgh. mode, buf .msgh. sub_mo
MAXMSGDATA,buf .mdata, &buf .msgh. size, &buf .msgh) ) {
Warn ( "ListenOnConn (%s : %d) : Qsar error. Will make NACKJMODE" , IP2Name ( buf .msgh. mode = NACK MODE; // Perhaps QsarO will set buf .msgh itsel
} else buf . msgh . mode = ACK_MODE; // Added 1/20/96 for recipts
// Generate an ACK to the sending QNETD buffer
Diag ("ListenOnConn (%s:%d) : After QsarO MODE=%d " , IP2Name (ip) , s, buf .msg buf .msgh. to_node = ip; // send back to orign _ J buf .msgh. to_port = port; // send back to orign (port not used) Diag ( "ListenOnConn (%s : %d) : Sending n/ACK_MODE to %p [%s] " , IP2Name dp) , s if (SendRemoteMess (&buf, 0) ) Warn ( "ListenOnConn (%s : %d) : Could not SendRemoteMess (ACK) ", IP2Name ( i break; case GET_MODE:
Warn ( "ListenOnConn (%s : %d) : GETJMODE not supported" , IP2Name (ip) , s) ,• break; case ACKJMODE : case ADMINREP_MODE : case QNETDREP_MODE: abuf = SMBUFADDR(bnum = buf . msgh. from_smbuf) ; // Target of ACK
Diag ( "ListenOnConn (%s : %d) : Relaying ACK to buffer %d" , IP2Name dp) , s,bnu memcpy (&abuf->msgh, &buf .msgh, re) ; // Copy all bytes received to ACKs ta
// Notify the sender if ( [ReleaseSemaphore (SYNC [bnum] .ackh,l,0))
Warn ( "ListenOnConn (%s :%d) : ReleaseSemaphore ack %d #%d" , IP2Name (ip) , break; case NACK_MODE: abuf = SMBUFADDRfbnum = buf .msgh . from_smbuf ) ; // Target of ACK
Diag ( "ListenOnConn (%s : %d) : Relaying NACK to buffer %d" , IP2Name (ip) , s, bn memcpy (&abuf->msgh, Sbuf .msgh, re) ; // Copy all bytes received to ACKs ta
// Notify the sender if ( I ReleaseSemaphore (SYNC [bnum] .ackh,l,0))
Warn ( "ListenOnConn (%s :%d) : ReleaseSemaphore ack %d #%d" , IP2Name (ip) , break; case QNETDREQ_MODE :
// Set up the reply message ' s data buf .msgh. ode = QNETDREP_MODE ; // send back to orign buf .msgh. to_node = ip; // send back to orign buf .msgh. to_port = port; // send back to orign (port not used)
if (buf .msgh. sub_mode == NETMAN_SMBUFH) {
Diag ( "ListenOnConn (%s : %d) : QNETDREQ_MODE sending SMBUFH=%d bytes", IP memcpy (Sbuf .mdata, sm_base, (sizeof (SMBUFH) - (2 * MAXRTSIZE) ) ) ; buf .msgh. size = (sizeof (SMBUFH) - (2 * MAXRTSIZE)),-
} else if (buf .msgh. sub_mode == NETMAN_SMBUFS) { lpBSA b = (lpBSA) &buf .mdata; b->nsbuf = SHAREDATA (nsbuf) ; for (i=0; i < SHAREDATA (nsbuf) ; i++) memcpy (&b->bs [i] , SMBUFADDRd) , sizeof (BS) ) ,- buf .msgh. size = sizeof (BSA) ; } else if (buf .msgh. sub_mode == NETMANJSOCKETS) {
IpSSA b = (IpSSA) &buf.mdata;
IpST stp = STroot; b->sockets = 0; while (stp) { b->ss [b->sockets] . ip = stp->ip; b->ss [b->sockets] .port = stp->port; stp = stp->next; b->sockets++;
} b- >ss [b- >sockets] . ip = 0 ; b- >ss [b- >sockets] . port = 0 ; buf . msgh . size = sizeof (SSA) ;
} else if (buf .msgh . sub mode == NETMANJRTJREAD ) { lpRTA b = (lpRTA) &buf .mdata; if (SHAREDATA (rt_pingpong) ) memcpy (&b->RT, &SHAREDATA(RT [1] ) , MAXRTSIZE ); else memcpy (&b->RT, &SHAREDATA(RT [0] ) , MAXRTSIZE ) ,- buf .msgh. size = MAXRTSIZE; } else if (buf .msgh. sub_mode == NETMAN_CLRJFOL) { SHAREDATA (failed_servers) = 0; buf .msgh. size = 0; } else if (buf .msgh. sub_mode == NETMAN_RT_NEW) { / BROADCAST ♦/ FILE *RTFP = fopen (ROUTNAME, "w") ; // Routing Table File
Say ( "ListenOnConn (%s : %d) : QNETDREQ_MODE NETMANJRT_NEW I %s %d bytes" if (RTFP) { if ( buf .msgh. size != (int) fwrite (&buf .mdata, sizeof ( char ), buf Warn ( "ListenOnConn (%s : %d) : QNETDREQ_MODE NETMAN_RT_NEW trouble fclose (RTFP) ,-
// ReadRTO is called by qnetd watchdog. c when file date changes } else Warn ( "ListenOnConn (%s : %d) : QNETDREQ_MODE NETMANJRT_NEW can't open buf .msgh. size = 0; } else if (buf .msgh. sub_mode == NETMAN_RT_GET) {
FILE ^RTFP = fopen (ROUTNAME, "r") ; // Routing Table File
Say ("ListenOnConn (%s:%d) : QNETDREQ_MODE NETMAN_RT_GET %s" , IP2Name (ip if (RTFP) { buf .msgh. size = fread (&buf .mdata, sizeof ( char ), MAXMSGDATA, RTFP) if ( Ibuf .msgh. size)
Warn ("ListenOnConn ( s : %d) : QNETDREQ_MODE NETMAN_RTJGET can't re fclose (RTFP) ; } else
Warn ( "ListenOnConn (%s : %d) : QNETDREQ_MODE NETMAN_RT_GET can't c } else if (buf .msgh. sub_mode == NETMANJTRAN) {
} else {
Warn ( "ListenOnConn (%s : %d) : QNETDREQ_MODE unknown submode %d",IP2Name buf .msgh. size = 0; } if (SendRemoteMess (&buf, 0) )
Warn ( "ListenOnConn (%s : %d) : Could not SendRemoteMess (QNETDREP_MODE) " break ; default :
Warn ( "ListenOnConn (%s :%d) : Got a message I dont understand type=%d" , IP2
}
Diag ("ListenOnConn (%s :%d) : waits for another message" , IP2Name dp) , s) ;
}
Say ("ListenOnConn (%s:%d) : Done Reading socket Good Bye" , IP2Name dp) , s) ,- RemoveSocket (s) ; ExitThread(O) ; return (0) ,-
DWORD ListenConnO {
SOCKET sClient,sServer = INVALIDJSOCKET; // SOCKADDR saClient; SOCKADDR_IN sas_in, sac_in; lpRT his_node; int sizeofsocket = sizeof (SOCKADDR) ;
//char hostname [NAMESIZE] ;
DiagC'ListenConn Thread");
//hostname now set by shm_init()
//if (gethostname (hostname, sizeof (hostname)))
// Fail ("QNETDlistenConn: gethostname failed WSAGetLastError () =%d" ,WSAGetLa if ( I (this_node = RTByName (SHAREDAT (hostname) ) ) )
Fail ("QNETDlistenConn: Could not find local node %s in %s" , SHAREDATA (hostn
Diag ("QNETDlistenConn: host=%s listens_on=%d" , SHAREDATA (hostname) ,this_node->
// (2) Establish a Socket if ((sServer = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
Fail ("QNETDlistenConn: Unable to open socket, WSAGetLastError ( ) = %d" , WSAGetLastError () ) ,-
// (3) Bind the socket
// _WNetGetHostAddress ("bob" , "wnetbnch", "tcp", &sa) ; sas_in.sin_family = AF_INET; sas_in. sin_port = htons ( (short) this_node->qnetd_port) ; sas_in.sm_addr.s_addr = htonl (INADDR_ANY) ; if (bind(sServer, (LPSOCKADDR) &sas_in, sizeof (sas_in) ) != 0)
Fail ("QNETDlisten: Unable to bind socket, WSAGetLastError ( ) = %d" , SAY_WSAERRORJTEX ( ) ) ; if (listen (sServer, 5)) // 5 is max number of mess to buffer Fail ("QNETDlisten: Listen failed WSAGetLastError 0 = %d" , SAY_WSAERROR_TEXT ( ) ) ;
while (TRUE) {
HANDLE thread_h;
DWORD thread_id;
IpST stab; // Socket table entry pointer
Diag ("QNETDlisten: Waiting for client connections..."),- sClient = accept (sServer, (LPSOCKADDR) &sac_in, ksizeofsocket) ,- Diag ("QNETDlisten: Got connected to a clinet"); Diag ("QNETDlisten: Clinets ID in network format ip=%p port=%d" , sac_in. sm_addr . s_addr, sac_in. sin_port) ; Diag ("QNETDlisten: Clinets ID in regular format ip=%p port=%d" , ntohl (sac_in.sin_addr.s_addr) , ntohs (sac_in. sin_port) ) ; stab = AddSocketToTable (sClient, &sac_in) ;
Diag ("QNETDlisten: Creating thread"),- thread_h = CreateThread (NULL, 0, (LPTHREAD_STARTJROUTINE) ListenOnConn, stab, 0, &thread_id) ;
} return (0) ,-// This cant happen } typedef struct lpar { // Message header
SOCKET skt; // socket number
SOCKADDR_IN sac; // inet address of client } LPAR, ♦lpLPAR;
IpST FindOrMakeSocket (IpSMBUF buf) { int trouble = 0; IpST stp; IpST stp_new; SOCKADDR_IN sas_in,- HANDLE thread_h ; DWORD thread_id;
if ((stp = FindSocket (buf ->msgh.to_node) ) == NULL) {
Diag ("FindOrMakeSocket (%p) : Making new socket ." ,buf->msghJto_node) ,- stp_new = (IpST) malloc (sizeof (ST) ) ,- stp_new->next = NULL; stp_new->ip = buf ->msgh . to_node ; stp_new->port = buf->msgh. to_port ,- // Not used if ( (stp_new->s = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
Warn ( "FindOrMakeSocket (%p) : Unable to open socket, WSAGetLastError () = buf->msgh. to_node, SAY_WSAERROR_TEXT ( ) ) ; free (stp_new) ; } else {
// setsockopt (stp->s, IPPROTO_TCP, TCP_NODELAY,
// (LPSTR) kbNoDelay, sizeof (BOOL)); sas_in.sin_family = AF_INET; sas_in . sm_port = htons ( (short ) buf - >msgh . to_port ) ,- sas_in. sin_addr.s_addr = htonl (buf->msgh. to_node) ; if (connec (stp_new->s, (LPSOCKADDR) &sas_in, sizeof (sas_in) ) != 0) { Diag ( "FindOrMakeSocket (%p) : connect 0 failed, WSAGetLastError () = %d buf- >msgh . o node , SAY_WSAERROR_TEXT 0 ) ; f ee (stp_new) ;
} else { stp_new->port = ntohs (sas_in. sin_port) ,-
Diag ( "FindOrMakeSocket (%p) : Connected to server on port %d",buf->msg Diag ("FindOrMakeSocket : Starting new listening thread"),- thread_h = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) ListenOnConn, stp_new, 0 , &thread_id) ,-
// Add to top of the chain stp_new->next = STroot;
STroot = stp_new; stp = stp_new;
// Sleep (500); // make sure args are copied before exit this routine
, ' ' return (stp) ; }
IpST AddSocketToTable (SOCKET sock, SOCKADDR_IN sa) { int ip = ntohl (sa->sin_addr .s_addr) ,- int port = ntohs (sa->sin_port) ; IpST stp;
DiagC'AddSocketToTable : s=%d ip=%p" , sock, ip) ; if (stp=FindSocket (ip) ) { stp->s = sock; } else { stp = (IpST) malloc (sizeof (ST) ) ; stp->s = sock; stp->ip = ip,- stp->port = port; stp->next = STroot; // add to front of the list STroot = stp;
} return (stp) ,-
}
/* FAILOVER:
First try the existing IP connection 2 times
Then we will find a NEW IP and try that connection.
*/
int SendRemoteMess (IpSMBUF buf, int pass) {
// Called from QNETD, TCP/ListenOnCon
//
// Pass tells how many times we have been called.
//
IpST skt ; int sentsize; int msgsize = sizeof (MSGH) + buf->msgh. size,
Diag ( "SendRemoteMess : About to FindOrMakeSocket mode=%d" , buf->msgh.mode) ; if (I (skt = FindOrMakeSocket (buf )) ) {
Warn ("SendRemoteMess : Could not FindOrMakeSocket for ip=%d" ,buf->msgh. to__n } else {
Diag ("SendRemoteMess : About to send mode=%d data: %s" , buf->msgh.mode, buf ->m sentsize = send(skt->s, (char ♦) &buf->msgh, msgsize, 0) ,-
if (sentsize == msgsize) { // Send was good Diag ( "SendRemoteMess : send completed"); SHAREDATA (stat . tx) ++; // Mess sent statistics return (0) ; // Good } else if (sentsize == -1) { // Send Error
Warn ("SendRemoteMess: sendO error=%d", SAYJWSAERRORJTEXT ( ) ) ; RemoveSocket (skt->s) ; // Try to ReOpen the TCP Conn if (pass++ < 2) {
Warn ( "SendRemoteMess : Remaking the connection"); return (SendRemoteMess (buf,pass) ) ,-
} } else { // sentsize != msgsize ; No error but not completed Warn ( "SendRemoteMess : did not send full message, sent %d of %d bytes" sentsize, buf ->mdata) ,-
} return (1) ,- // Bad
/* **
♦♦ Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
** OR DISCLOSURE.
**
** THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
♦♦ TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
** OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA':
**
** OpenMQ
** Module: qnetd.c
** Author: Derek Schwenke 9/8/95
**
*/ ttinclude "qlib.h" ttinclude "qnetd.h"
DWORD WatchDogO { int sec=0;
BY_HANDLE_FILE_INFORMATION Info; FILETIME LastTime; HANDLE RTF = CreateFile ( ROUTNAME ,
GENERIC_WRITE | GENERICJREAD,
FILE_SHARE_WRITE | FILE_SHARE_READ, 0 ,
OPEN_ALWAYS ,
FILE_ATTRIBUTE_NORMAL, 0) ; while (1) {
Sleep (1000) ; // One second time ( &SHAREDATA (time) ) ; if (sec++ >= 15) { sec = 0 ; if (RTF LS GetFilelnformationByHandle ( RTF, fclnfo )) {
//DiagC'WatchDog: RT file time = %d %d" , Info. ftLastWriteTime.dwHig if (memcmpf&LastTime, &Info.ftLastWriteTime, sizeof (FILETIME) ) ) { memcpy (SLastTime, &Info.ftLastWriteTime, sizeof (FILETIME) ) ,- SayC'WatchDog: calls ReadRT"); ReadRT ( ) ; } // file time differs } // GetFilelnformationByHandle } // 15 seconds } // forever
CloseHandle (RTF) ,- return ( 0) ;
} /* **
♦ Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
*♦ UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
♦♦ LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
♦♦ OR DISCLOSURE.
**
♦ THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
♦ TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
♦ OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
♦ OpenMQ
♦ Module: ramq.c
♦ Author: Derek Schwenke 9/8/95
**
♦ This is a single threaded ram queue */
// Each message could be an enq or a deq. ttinclude "qlib.h" ttdefine QSIZE 8 ttdefine ENQ ramq [ramq_head] ttdefine DEQ ramq [ramq_tail] ttdefine ENTRIES ((( ramq_head + QSIZE ) - ramq_tail) % QSIZE)
SMBUF ramq [QSIZE] ; int ramqjhead = 0; // points to empty space int ramq_tail = 0; // points to filled entry
int main (int argc, char **argv) { lpQHANDLE q; int status; char qname [NAMESIZE] ; if(argc> 1) strcpy (qname, argv [1] ) ; else strcpy (qname, "Ql") ;
Say("RAMQ(%s) : About to Qopen", qname) ; if (!(q = Qopen (qname, GETTING) ) )
Say ("RAMQ(%s) Could not open the queue" , qname) ,-
while (QSUCCESS == Qgnp_get (q, 0 , 0 , &ENQ .msgh, ENQ . mdata, MAXMSGDATA) ) { Say ("RAMQ(%s) Server Got : %s" , qname, ENQ .mdata) ; if (ENQ. msgh.mode == PUTTING) {
Say ("RAMQ (%s) : ENQUEs message %s" , qname, ENQ. mdata) ; ramqjhead = ++ramq_head % QSIZE; if (ramqjhead == ramq_tail) Say ( "RAMQ (%s) : OVERFLOW I ", qname) ; Qgnp_pu (q, ACK, 0,0) ; else if (ENQ. msgh. mode == REQUESTING) { if (ramq_head == ramq_tail) {
Say ( "RAMQ (%s) : EMPTY" , qname) ;
Qgnp put (q, EMPTY, 0,0); } else J
Say ("RAMQ (%s) : DEQUES message %s" , qname, DEQ. mdata)
Qgnp_put(q, RETURN_DATA, DEQ.mdata, DEQ .msgh. size) ramq_tail = ++ramq_tail % QSIZE;
} else {
Say ( "RAMQ (%s) : Unexpected Mode=%d" , qname , ENQ . msgh . mode)
Qgnp put (q, NACK, 0, 0); }
Say("RAMQ(%s) has %d entries .", qname , ENTRIES) ; }
Ask ( "RAMQ (%s) : all done", qname) return (0) ,-
User: root Host : bunny Class : bunny Job: stdin
0001G1 /* **
** Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
** OR DISCLOSURE.
**
** THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
** TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
** OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
** OpenMQ
** Module : ramq . c
** Author: Derek Schwenke 9/8/95
**
** This is a single threaded ram queue
*/
// Each message could be an enq or a deq. ttinclude "qlib.h" ttinclude "qadmin.h" // Que entry states : ttdefine INVALID 0 ttdefine VALID 1 ttdefine PENDING_PUT 2 ttdefine PENDING GET 3 ttdefine MAXQSIZE 1001 ttdefine MAXRAMQDATA 100 ttdefine ENQ ramq [ramq_head] ttdefine DEQ ramq [ramq_tail] ttdefine MES ramq [ramq_mess] ttdefine MODE ENQ . msgh . mode ttdefine FLAGIS(X) BITSET(X, ENQ.msgh. flags) ttdefine QINC(X) X = ++X % QSIZE ttdefine QDEC(X) X = --X % QSIZE ttdefine USEDSPACE ( ( ( ramqjhead + QSIZE ) - ramq_tail) % QSIZE) ttdefine ALLENTRIES (st . committed entries st . pending_gets + st .pending_puts) typedef struct rqbuf { //Ramq int status; MSGH msgh; char mdata [MAXRAMQDATA] ;
} RQBUF, *lpRQBUF;
QADMSTATS st; // Statistics
RQBUF ramq [MAXQSIZE] ; int QSIZE = MAXQSIZE; int ramq_head = 0; // points to empty space int ramq_tail = 0; // points to filled entry int ramq_mess = 0; // points to entry that was just filled char qname [NAMESIZE] ,-
void PrintQ ( ) { char n [80] ,- int 000162 for ( i QSIZE ι++ ){ if (ramq [i] . status == INVALID) // Clear entry just for display *ramq [i] .mdata = ramq [i] .msgh. mid. host = ramq [i] .msgh. mid. tid 0; strcpy (n, " " ) ; if (i == ramq_head) strca (n, " <- head"); if (i == ramq_tail) strcat (n, " <- tail"); Say(" %d mid=%p:%d status=%d : %s%s",i, ramq [i] .msgh. mid. host, ramq [i] .msgh. mid. tid, ramq [i] . status, ramq ] . mdata, n) ;
void StatReset (char *qname) { st . amt_free_dspace = -1; st.num_puts = 0 ,- st . num_gets = 0 ; s .num_commits = 0 ; st .num_aborts = 0 ,- if (qname) strcpy (st .physical_qname, qname) ; if (qname) strcpy (st . logical_qname, "") ,- st. max entries limit = MAXQSIZE - 1; } void QueReset (char ♦qname)} int i ; for (i = 0; i < QSIZE ; i++) ramqfi] .status = 0 ;
StatReset (qname) ; st . committed_entries = 0; s .pending_gets = 0; st .pending_puts = 0 ; ramq_head = ramq_tail = 0; st . num_restarts++ ; st .last_restart_time = SHAREDATA ( time) ; st.node_address = SHAREDATA (hostip) ; strcpy (st .node name, SHAREDATA (hostname) ) ,- }
void SetSizednt size) { // Resize the que size++; // Internaly it one lager
QSIZE = size;
QueReset (NULL) ; } int FindNthMess (int nth, int mstatl, int mstat2) { // Finds adm req data int p = ramq_tail; nth++; while ((nth) && (p != ramq_head) ) { if (ramq [p] .status == mstatl || ramq [p] .status == mstat2 ) nth--,-
QINC (p) ; } if (nth) return ( -1) ;
0D01 B3 else return (QDEC(p) ) ;
void tran (action) { // COMMIT or ABORT all parts of a transaction int p_gets = st .pending_gets, i; int p_puts = s .pending_puts; Diag ("RAMQ-TRAN: %d mid=%p : %d" , action, MES .msgh. mid. host , MES . msgh.mid .tid) ; for (i = 0 ; i < QSIZE ; i++) if (ramq [i] .msgh. mid. tid == MES .msgh. mid. tid) if (ramq [i] .msgh. mid. host == MES .msgh. mid. host) if (ramq [i] .status == PENDING_PUT) { // Uncommitted PUT if (action) { ramq [i] .status = VALID; // Committed put st . num_puts++ ; st . committed_entries++ ; } else ramq[i] .status = INVALID; // Aborted put st .pending_puts- - ; } else if (ramq [i] . status == PENDINGJ3ET) { // Uncommitted GET if (action) { ramq [i] . status = INVALID; // Committed get st . num_gets++; } else { ramq[i] .status = VALID; // Aborted get st . committed_entries++ ;
} st . pending_gets-
if ( (p_gets == st .pending_gets) && (p_puts == st .pending_puts) )
Warn ( "tran (%d) did not commit or abort anything" , action) ,- //if (p_gets = p_gets - st .pending_gets) Say ( "tran (%d) clears %d gets",actio //if (p_puts = p_puts - st .pending_puts) Say ( "tran (%d) clears %d puts",actio if (DEQ. status == 0 && ramq_head != ramq_tail) Diag ( "RAMQ-TRAN: Adjusting Tail while (DEQ. status == 0 && ramqjhead != ramq_tail) //Adηust the tail QINC(ramq_tail) ; if (action) s .num_commits++; else st .num aborts++;
DWORD RQ ( ) { lpQHANDLE q; int x; char keys [MAXMSGDATA] ; lpQADMCTLS pCTL // Cast to ramq[].data lpQADMSEL pKEY lpMID pMID
Say ( "RAMQ (%s) : %d Entires" , qname, QSIZE - 1) ,- if (!(q = Qopen (qname, GET_MODE, 0,0, 0,0,0)) )
Say("RAMQ(%s) Could not open the logical queue", qname) ,-
f)nn±£4 st .num_restarts = -1; st .first_start_time = SHAREDATA (time) ; s .qget_state = 1; // enable puts st .qput_state = 1; // enable gets
QueReset (qname) ; while (QSUCCESS == QlistenBeforeReply (q, &ENQ. msgh, ENQ. mdata, MAXMSGDATA) ) {
Diag ( "RAMQ (%s) Server Got md=%d mid:%p: d : %s ", qname , MODE, ENQ .msgh .mid . hos ramq_mess = ramq_head; // mess is where the last message went. if (MODE == PUT_MODE) { if ( 1st .qput_state) {
Say ( "RAMQ (%s) put is disabled I ", qname) ,-
QreplyAfterListen (q,ACK_MODE, SUB MODEJDISABLED, 0,0,0); } else if (USEDSPACE >= QSIZE - 1) J
Say ("RAMQ (%s) is FULL I ", qname) ;
QreplyAfterListen (q,ACK_MODE,SUB_MODE_FULL, 0,0,0) ; } else { - ■
Diag ("RAMQ (%s) : ENQUEs message %s ", qname , ENQ . mdata) ; if (FLAGIS (QJTRAN) ) {
ENQ. Status = PENDING_PUT; st . pending_puts++; } else {
ENQ. status = VALID; st . num_puts++ ; st. committed entries++; }
QINC(ramq_head) ,-
QreplyAfterListen (q, ACK_MODE , SUB_MODE_OK, 0,0,0);
} else if (MODE == REQUEST_MODE) { // Find next valid message int g = ramq_tail; while (ramq [g] .status != VALID && g != ramqjnead) QINC(g); if ( 1st .qget_state) {
Say ("RAMQ(%s) get is disabled! ", qname) ;
QreplyAfterListen (q,ACK_MODE,SUB_MODE_DISABLED, 0,0,0) ; } else if (g == ramq_head) {
Diag ( "RAMQ (%s) : is EMPTY I ", qname) ;
QreplyAfterListen (q, ACK_MODE, SUB_MODE_EMPTY, 0,0,0); } else {
Diag ( "RAMQ (%s) : DEQUES message %s" , qname, ramq [g] .mdata) ,-
QreplyAfterListen (q, ACK_MODE, SUB_MODE_OK, ramq [g] .mdata, ramq[g].ms if (FLAGIS (QJTRAN) ) { ramq [g] .status = PENDINGJGET; // Uncommtted get memcpy (&ramq[g] .msgh. mid, &ENQ. msgh. mid, sizeof (MID) ) ,- // This MSG st . pending_gets++ ; } else { ramq [g] .status = INVALID; // Committed get st. num gets++;
} s .committed_entries-- ; while (ramq [ramqjtail] .status == INVALID && ramqjhead != ramq_tail) QINCtra q tail); //Adjust the tail } else if (MODE == ADMINREQ_MODE) { // Administrative messages switch (ENQ. msgh. sub_mode) { case QADM_REQ_STATS : st .max_entries = QSIZE - 1; st.holey_entries = USEDSPACE - ALLENTRIES ; s .num_free_entries = QSIZE - 1 - USEDSPACE;
QreplyAfterListen(q,ADMINREP_MODE,SUB_MODE_OK, (char ) &st, sizeof (s
break ; case QADM_REQ_COM_DATA : if (-1 != (x = FindNthMess ( (int) *ENQ. data, VALID, ALID) ) )
QreplyAfterListen (q, ADMINREP_MODE, SUBJMODEJOK, ramq [x] .mdata, 0,& else
QreplyAfterListen (q, DMINREP_MODE, 0 , 0, 0,0); break; case QADM_REQ_UNCOM_DATA: if (-1 != (x = FindNthMess ( (int) *ENQ. mdata, PENDINGJPUT, PENDING_GET) QreplyAfterListen(q,ADMINREP_MODE,SUB_MODE_OK, ramq[x] .mdata, 0,& else
QreplyAfterListen(q,ADMINREP_MODE,0, 0, 0,0); brea ; case QADM_SET_CONTROLS : pCTL = (lpQADMCTLS) &ramq [ramq_mess] .mdata, st .qput_state = pCTL->enable_qputs_flag; s .qget_state = pCTL->enable_qgets_flag;
Say("%d qput_state" , st .qput_state) ; Say("%d qget_state" , st .qget_state) ; if ( pCTL->stats_reset_flag ) StatReset (qname) ,- if ( pCTL->full_reset_flag ) QueReset (qname) ,- if ( (pCTL->max_entries_value != QSIZE - 1) && (pCTL->max_entries_val
SetSize (pCTL->max_entries_value) ; QreplyAfterListen(q,ADMINREP_MODE,SUB_MODEJOK, 0, 0,0); if ( pCTL->shutdown_ lag ) { Qclose (&q, 0) ; exit(0);}
// PrintQO ,- break; case QADMJREQ_MSG :
{ int e = ramq_tail; pMID = (lpMID) &ramq [ramq_mess] .mdata ;
DiagC'Finding mid %p %d %d" ,pMID->host ,pMID->tid,pMID->uid) ; while (e != ramq_head) { if(0 == metncmp (&ramq [e] .msgh. mid, &ramq [ramq_mess] .mdata, sizeof e = QINC(e) ; if ( (e == ramqjhead) || (ramq [e] . status != VALID)) x = 0; else x = ramq [e] .msgh. size; QreplyAfterListen (q, ADMINREP MODE, SUB MODE OK, ramq [e] .mdata, x } - - - break ; case QADM_REQ_SEL_DATA : // KEY SEARCH pKEY = (lpQADMSEL) &ramq [ramq_mess] .mdata; pMID = (lpMID) Sckeys; if (pKEY->num_preds) { int gt,lt, e = ramq_tail, p, p_matches = 0; if (pKEY->search_type == SEARCH_UNCOM_ENT) {gt = PENDINGJPUT else if (pKEY->search_type == SEARCH_ALL_ENT ) jgt = VALID; It = else (gt = It = VALID; while (e != ramq_head) { // Scan the que looking for a match if ( (ramq [e] . status >= gt) && (ramq [e] . status <= It) ) { p_matches = 0; for (p = 0; p < pKEY->num_preds; p++) { if ((UINT) pKEY->preds[p] .offset < (sizeof (MSGH) + ramq [ if (pKEY->preds [p] .pred_type == INT_SEARCH_TYPE) { //int iv = *( (int*) ( (char *) &ramq [e] .msgh + pKEY-> if ( (pKEY->preds [p] .min_switch == 0) I I (pKEY->preds [p] .min_int_val < = * ( (int*) ( (char ) &ramq [e] .msgh + pKEY->preds [p] p_matches++; if ( (pKEY->preds [p] .max_switch == 0) I I (pKEY->preds [p] .max_int_val > = *( (int*) ( (char ) {.ramq [e] .msgh + pKEY->preds [p] p_matches++;
} else if (pKEY->preds [p] .pred_type == SHORT_SEARCHJT if ( (pKEY->preds [p] .min_switch == 0) I I (pKEY->preds [p] .min_sh_val < = ( (short ( (char ) &ramq [e] .msgh + pKEY->preds[ p_matches++; if ( (pKEY->preds [p] .max_switch == 0) I I (pKEY->preds [p] .max_sh_val >= ( (short*) ( (char *) &ramq [e] .msgh + pKEY->preds[ p_matches++;
} else if (pKEY->preds [p] .pred_type == STR_SEARCH_TYP if ( (pKEY->preds [p] .min_switch == 0)
| | (0 >= strncmp (pKEY->preds [p] .min_str_val, ((char *) &ramq[e] .msgh + pKEY->preds [p] .of fset) p_matches++; if ( (pKEY->preds [p] .max_switch == 0)
| | (0 <= strncmp (pKEY- >preds [p] .max_str_val, ((char *) &ramq [e] .msgh + pKEY->preds [p] .of f set) p matches++;
} } // offset within size
} // for 3 predicates if (p_matches == 2 * pKEY->num_preds) { memcpy (pMID, &ramq [e] . sgh. mid, sizeof (MID) ) ; pMID = (lpMID) ( (char *)pMID + sizeof (MID) ) ;
} // if Valid e = QINC(e) ; } // Scan que nn ^
00016' } // Predicates
Diag ("Matches = %d",(x = (((char *)pMID - keys) / sizeof (MID) ) ) ) ;
QreplyAfterListen(q,ADMINREP_MODE, SUB_MODE_OK, keys, ((char *)pMID break ,- default: Say ( "What?" ) ; }
} else if (MODE == COMMIT_MODE) { tran(l) ; QreplyAfterListen (q,ACK_MODE,SUB_MODE_OK, 0, 0,0);
} else if (MODE == ABORT_MODE) { tran(0) ,- QreplyAfterListen (q, ACK_MODE , SUB_MODE_OK, 0, 0,0);
} else {
Warn ("RAMQ (%s) : Unexpected Mode=%d", qname, ENQ. sgh. mode) ; QreplyAfterListen (q, ACK MODE, SUB MODE BAD REQ, 0, 0,0); // Unexpected m
} " " " if (FLAGIS (QJTRANJEND) ) tran(l);
Diag ( "RAMQ (%s) has %d entries %d not commited .", qname, st . committed_entries, st .pending_puts + st .pending_gets) ,- if (MODE != ADMINREQJMODE) if (SHAREDATA (diag) ) PrintQO; // Print the que
Say ( "Bye " , qname) return (0) ;
int main (int argc, char ♦♦argv) { HANDLE hRQ; DWORD idRQ; if (argo 1) strcpy (qname, argv [1] ) ; else strcpy (qname, "QS1") ,- if (argo 2) { sscanf (argv [2] , "%d" , &QSIZE) ,-
QSIZE++;
QSIZE = min (MAXQSIZE, QSIZE) ,-
QSIZE = max (2, QSIZE) ; } ~ hRQ = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) RQ, 0,0,&idRQ);
AskC'All done") ,-
Qclose (NULL, qname) ; // Removes shared buffer so messages dont need to time-ou return (0) ,-
000169 /* **
** Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
* * LAWS OF THE UNITED STATES . USE OF A COPYRIGHT NOTICE ** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
* * OR DISCLOSURE. **
* * THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
* * TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
* * OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR ** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
* * ** OpenMQ ** Module: ramqcs . c
* * Author: Derek Schwenke 9/8/95
* * ramq ' s client and server
* *
*/ ttinclude "qlib.h" ttinclude "rt.h" ttinclude "qadmin.h" void Help {
Say "0 <name> - Open " ) ;
Say "P <data> - Put " ) ;
Say "G - Get") ;
Say "B - Begin tran") ;
Say "C - Commit tran" ) ,-
Say "A - Abort tran" ) ;
Say "E - End tran on next op")
Say "S - Single tran op") ,-
Say "N - No tran" ) ;
Say "L - List status" ) ,-
Say "D - Diagnostics on/off ");
Say "R - Reset all") ;
Say - Reset statistics"),-
Say "K - Shutdown") ;
Say "Q <put/get> - Enable/disable ops");
Say "H - Help") ;
Say "Z <numb> - Set size of que");
} main (int argc, char **argv) { int ret, i, flags=0, next_flag=0, sz; char qname [NAMESIZE] ; MSGH mh ; lpQHANDLE Q; lpQADMSTATS pSTA = (lpQADMSTATS) AskAnswer; // lpQADMCTLS pCTL = (lpQADMCTLS) AskAnswer; QADMCTLS ctl; memset (&ctl, 0, sizeof (ctl) ) ,- ctl . enable_qputs_flag++; ctl . enable_qgets_flag++; if (argc==2) strcpy (qname, argv[l] ) ; else strcpy (qname, "Ql") ,- // appl
Say ( "RAMQCS : Server=%s " , qname) ; // Open the queue for putting if ( I (Q = Qopen (qname, PUT_MODE, 0, 0,0,0,0) ) )
Warn( "RAMQCS : could not open the que %s", qname);
// Put data into the que
Say ("Open Put Get Begin End Commit Abort Single List Kshutdown sTat size Rese whilet strle (Ask ( "ramqcs") ) ) { ttdefine SAR_WAS_0K(A1, A2, A3 , A4 , A5 , A6 , A7 , A8 , A9 , A10) QSUCCESS >= (ret = QsendAndR if (strchr ( "Pp" , AskAnswer) && AskAnswer [1] == ' ' && strlen (AskAnswer) > if (SAR_WAS_OK(Q,PUT_MODE, 0, flags, strlen (AskAnswer) , &AskAnswer [2] , LINESIZE, AskAnswer, &sz, &mh) ) { if (ret == QSUCCESS_FAILOVER) SayC'RAMQCS: Failover successfull " ) ; if (mh.mode == ACK_MODE && mh.sub_mode == SUB_MODE_OK)
SayC'RAMQCS: Succeeded: (mode=%d) %s'i , mh.mode, AskAnswer) ; else if (mh.sub_mode == SUB_MODE_FULL)
SayC'RAMQCS: que was FULL"); else
SayC'RAMQCS: Put failed %d" ,mh. sub_mode) ,- } else
SayC'RAMQCS: Qput comm error"),- flags = next flag; } else if (strchr ( "Gg" , *AskAnswer) ) { // Get
I if (SARJWAS_OK(Q,REQUEST_MODE,0, flags , strlen (AskAnswer) +1 , AskAnswer ~ LINESIZE, AskAnswer, isz, &mh) ) { if (ret == QSUCCESS_FAILOVER) SayC'RAMQCS: Failover successfull ") ; if (mh.mode == ACK_MODE && mh.sub_mode == SUB_MODE_OK)
SayC'RAMQCS: Succeeded: (mode= d) %d bytes %s" , mh.mode, mh. size, As else if (mh.sub_mode == SUB_MODE_EMPTY)
SayC'RAMQCS: que was EMPTY"); else
SayC'RAMQCS: Qget failed %d" ,mh.sub_mode) ,- flags = next_flag;
else if (strchr ("Ll" , *AskAnswer) ) { // List if (QSUCCESS >= QsendAndReceive (Q,ADMINREQ_MODE,QADM_REQ_STATS, 0,0,0, sizeof (QADMSTATS) , AskAnswer, &sz, &mh) ) { int pg,pp,ce,he, fe,me;
Say ( " \n\n%s : %s %s %x" , pSTA- >physical_qname , pSTA- >logical_qname , pSTA- Say("%7d committed_entries" ,ce = pSTA->committed_entries) ,- Say("%7d pending_gets" ,pg = pSTA->pending_gets) ,- Say("%7d pending_puts" ,pp = pSTA->pending_puts) ,- Say("%7d holey_entries" ,he = pSTA->holey_entries) ; Say("%7d num_free_entries" , fe = pSTA->num_free_entries) ,- if (pSTA->amt_free_dspace != -1)
Say("%7d amt_free_dspace" ,pSTA->amt_free_dspace) ; if (pSTA->max_entries_limit >= pSTA->max_entries ) Say ("%7d max %4d limit", me = pSTA->max_entries, pSTA->max_entrie else
Say( %7d max ",me = pSTA->max_entries) ,- Say( %7d putstate %4d getstate" ,pSTA->qput_state,pSTA->qget_state) ,- Say( %7d puts %4d gets" ,pSTA->num_puts, pSTA->num_gets) ,- Say( %7d committs %4d aborts %d restarts" ,pSTA->num_commits,pSTA- a Say( \n\tFirst start time %s\tLast restart time %s", ctime (&pSTA->first_start_time) , ctime (&pSTA->last_restart_time) ) ; if (me - (ce + pg + pp + he + fe) ) Warn ( "REPORTED ENTRIES OFF BY %d",me - (ce + pg + pp + he + fe) ) ;
AskAnswer = i = 0; sz = 1; while (sz) {
*AskAnswer = i++; if (QSUCCESS >= QsendAndReceive (Q,ADMINREQ_MODE,QADMJREQ_COM_DATA 0, sizeof (int) , AskAnswer, LINESIZE, AskAnswer, &sz, &mh) ) if (sz) Say("%d : %s" , i , AskAnswer) ,-
AskAnswer = i = 0; sz = 1; Say ( " " ) ; while (sz) {
AskAnswer = i++; if (QSUCCESS >= QsendAndReceive (Q, ADMINREQ_MODE, QADMJREQJUNCOMJDA 0, sizeof (int) , AskAnswer, LINESIZE, AskAnswer, &sz, &mh) ) if (sz) Say("%d submode=%d : %s" , i , mh. sub_mode, AskAnswer) ;
else if (strchr ( "Qq" , ♦AskAnswer) ) { // Shutdown if ('0' == AskAnswer [4] ) ctl . enable_qputs_flag = 0 ; if ('1' == AskAnswer [4] ) ctl . enable_qputs_flag = 1; if ('0' == AskAnswer [8] ) ctl . enable_qgets_flag = 0 ,- if ('1' == AskAnswer [8] ) ctl . enable_qgets_flag = 1; if (QSUCCESS >= QsendAndReceive (Q,ADMINREQ_MODE,QADM_SET_CONTROLS, 0, sizeof (QADMCTLS) , (char*) &ctl, 0, 0,&sz, &mh) ) Say ("puts %d gets %d" , ctl .enable_qputs_flag, ctl . enable_qgets_flag
else if (strchr ("Kk" , ♦AskAnswer) ) { // Shutdown ctl . shutdown_flag++ ; if (QSUCCESS >= QsendAndReceive(Q,ADMINREQ_MODE,QADM_SET_CONTROLS,
0, sizeof (QADMCTLS) , (char*) &ctl , 0, 0, &sz, &mh) ) Say ( "Shutdown" ) ; ctl . shutdown_flag- - ;
else if (strch ( "Rr" , ♦AskAnswer) ) { // Reset ctl . full_reset_flag++ ,- if (QSUCCESS >= QsendAndReceive (Q,ADMINREQ_MODE,QADM_SET_CONTROLS,
0, sizeof (QADMCTLS) , (char*) &ctl, 0, 0 , &sz , &mh) ) Say ("full Reset"); ctl. full reset flag--; } else if (strchr ( "Zz" , *AskAnswer) && (sscanf (AskAnswer, "%*s %d",&i))) { if (d) < 2) Say ("Bad Size"),- else { ctl.max_entries_value = i; if (QSUCCESS >= QsendAndReceive (Q,ADMINREQ_MODE,QADM_SET_CONTROLS 0, sizeof (QADMSTATS) , (char*)&ctl, 0,0,&sz,&mh) ) Say ( "Size=%d" , i) ;
0001 7Z } ctl. max entries value = 0; } else if (strchr ( "Tt" , *AskAnswer) ) ( // Kleer ctl . stats_reset_flag++ ,- if (QSUCCESS >= QsendAndReceive (Q, ADMINREQ_MODE , QADM_SET_CONTROLS ,
0, sizeof (QADMCTLS) , (char*) fcctl, 0 , 0 , .sz , &mh) ) Say ("Stats reset") ctl. stats reset flag--,-
}
/* else if (strchr ( "x" , *AskAnswer) ) ( // Broadcast BroadcastRT ;
} else if (strchr ( "X" , *AskAnswer) ) ( // Get CopyRT (RT IP (RTByName (—AskAnswer [2] ) ) ) ,-
} */ else if (strchr ( "Hh" , *AskAnswer) ) HelpO; else if (strchr ( "Bb" , *AskAnswer) && I (flags & QJTRAN) ) (flags = QJTRANJBEGIN else if (strchr ( "Cc" , *AskAnswer) _&flags) (Qcommit (COMMIT_MODE) ,- flags = nex else if (strchr ( "Aa" , AskAnswer) __flags) {Qcommit (ABORT_MODE) ; flags = nex else if (strchr ( "Ee" , AskAnswer) ) (flags = Q_TRAN_END; next_flag = 0;} else if (strchr ( "Ss" , *AskAnswer) ) (flags = Q_TRAN_SINGLE; next_flag = 0;} else if (strchr ( "Nn" , *AskAnswer) ) (flags = next_flag = 0;} else if (strchr ("Dd" , *AskAnswer) ) (SHAREDATA (diag) = ( I SHAREDATA (diag) ) ; } else if (strchr ( "Oo" , *AskAnswer) && AskAnswer [1] == ' ' && (strlen (AskAnsw int open_flags = 0 ,- sscanf (AskAnswer, "%*s %s %lx" , qname, &open_flags) ;
SayC'RAMQCS: Open %s flags= x" , qname, open_flags) ; if ( I (Q = Qopen (qname, PUT_MODE, 0 , open_flags, 0, 0, 0) ) ) Fail ( "RAMQCS : could not open the que %s", qname); } else
Say ("Try again! ") ;
if (flags) Diag ( "RAMQCS : flags %p", flags);
}
SayC'RAMQCS: ALL DONE"); return (0) ,-
/* * *
** Copyrigh (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
♦♦ UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
*♦ LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
♦♦ IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
♦* OR DISCLOSURE.
**
♦♦ THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
♦ TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
♦* OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
♦* EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
♦♦ OpenMQ
♦* Module: ramqcs.c
♦♦ Author: Derek Schwenke 9/8/95
*♦ ramq's client and server **
*/ ttinclude "qlib.h" extern char AskAnswer [LINESIZE] ; main (int argc, char ♦argv) { int status, sz; char qname [NAMESIZE] ;
MSGH mh; lpQHANDLE Q;
ReadParms ( ) ;
// Name that q if (argc==2) strcpy (qname, argv [1] ) ; else strcpy (qname, "Ql" ) ; // appl Say ( "Server=%s" , qname) ;
// Open the queue for putting if C(Q = Qopen (qname, PUTTING) ) )
FailC'APPC: could not open the que %s", qname);
// Ask the user to Put or Get while ( strlen (As ("RAMQS: Put Get Open?"))) { if (AskAnswer == 'p' || AskAnswer == 'P') ( Q->msgh.mode = PUTTING; if (strlen (Ask ("RAMQS: Put messge" ) ) ) if (QSUCCESS == Qpng (Q, flags, strlen (AskAnswer) +1, AskAnswer, LINESIZE, AskAnswer, &sz, &mh) )
SayC'RAMQS: Succeeded: (mode=%d) %s" , mh.mode, AskAnswer) ; else
SayC'RAMQS: Qput failed"),-
else if (♦AskAnswer == 'g' || AskAnswer == 'G') { Q->msgh.mode = REQUESTING; if (QSUCCESS == Qpng(Q, flags, strlen (AskAnswer) +1, AskAnswer, LINESIZE, AskAnswer, &sz,&mh) ) SayC'RAMQS: Succeeded: (mode=%d) %d bytes %s ", mh . mode , mh. size , AskAns else
SayC'RAMQS: Qput failed") ;
}
else if (*AskAnswer == 'o' | | ♦AskAnswer == 'O' && strlen (AskAnswer) > 2) SayC'RAMQS: Open") ; sscanf (AskAnswer, "%+s %s" , qname) ,- if ( ! (Q = Qopen (qname, PUTTING) ) )
FailO'APPC: could not open the que %s", qname);
Say ( "RAMQS : ALL DONE" ) return (0) ;
///////////////////////////////////////////////////// ///////////////////////////
//
// Common admm defs used by OpenMQ Qservers
// ///////////////////////////////////////////////////////////////////////////// ttdef ine DISABLED OL ttdef e ENABLED IL ttdef ine QADM_REQ_STATS 2L ttdef ine QADM_REQ_SEL_DATA 3L ttdef ine QADM_REQ_MSG 7L ttdef ine QADM_REQ_COM_DATA 8L ttdef me QADMJREQJUNCOMJDATA 9L ttdef me QADM_SET_CONTROLS 10L ttdef ine SHORT_SEARCH_TYPE OL ttdef me INT_SEARCH_TYPE IL ttdef me STR SEARCH TYPE 2L ttdef ne SEARCH_ALL_ENT OL ttdef ine SEARCH_COM_ENT IL ttdef me SEARCHJJNCOMJENT 2L ttdef e KEY STR S IZE 50
typedef struc t qadmstats (
CHAR logιcal_qname [NAMESI ZE] , // logical que name
CHAR phys ιcal_qname [NAMESI ZE] , // physical que server name
CHAR node_name [NAMES I ZE] , // node name of que server int node_address ; // IP address of que server mt max_entrιes_lιmιt , // upper limit on max value int max_entπes , // current max value t commιtted_entnes ; // commited entries int pendιng_gets , // pending GET entries mt pendmg_puts ; // pending PUT entries int holey_entrιes ,- // ttholes in the queue mt num_f ree_entrιes ,- // ϋ of free entries that can be used mt amt_f ree_dspace ; // amt of free_space left queue short qget_state ; // gets_are_enabled short qput_state ; // puts_are_enabled int num_puts ; // committed puts only int num_gets ; // committed gets int num_commιts ; // tt of committed operations int num_aborts ; // # of aborted operations int nuπjrestarts ; // ϋ of server restarts time_t f ιrst_start_tιme ; // t me of fresh start tιme_t last_restart_tιme ; // time of last restart // mt num_recov_tr es ; // tιme_t last_recov_tιme ; } QADMSTATS , ♦lpQADMSTATS;
typedef struct qadmctls { int max_entrιes_value ; // extends max entries,- later... // mt clear_all_tran_flag; // cleans up stuck entries/compaction int full_reset_flag; int shutdown_flag; int stats_reset_flag; mt enable_qputs_flag; t enable_qgets_flag; }
Figure imgf000179_0001
typedef struct predstr { int pred_type ,- // predicate type int offset; // offset within QMSG structure short min_switch; // 1=ENABLED/DISABLED min switch short max_switch; // 1=ENABLED/DISABLED max switch short min_sh_val; // min short value short max_sh_val; // max short value int min_int_val ,- // min int value int max_int_val ; // max int value char min_str_val [KEY_STR_SIZE] ; // min string value char max_str_val [KEY_STR_SIZE] ; // max string value int min_str_len; // min string length int max str len; // max string length
} PREDSTR, lpPREDSTR; typedef struct qadmsel { int num_preds ; // number of predicates up to max of 3 int search_type; // SEARCH_ALL_ENT, SEARCH_COM_ENT, SEARCH_UNCO PREDSTR preds [3] ; // array of predicates
} QADMSEL, lpQADMSEL;
ttdefine MAXSEL
/* **
* * Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED. ** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT ** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE ** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION ** OR DISCLOSURE. **
* + THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND ** TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
* + OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR ** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA. ** ** OpenMQ ** Module : qget . c ** Author: Derek Schwenke 9/8/95
* * ** ** QgetO is made from two calls: ** QlistenBeforeReply () // Get new data ** QreplyAfterListen // Return ACK and maybe some data ** Both call must be made. **
*/
ttinclude " qlib . h " extern IpSMBUFH s base ; int Qget ( lpQHANDLE q, // Q handle returned by Qopen ( ) ; lpMSGH messh, // Pointer to message header to fill char mess, // Pointer to message buffer to fill int maxsize) // size of message buffer
// Always return 1st error found // Always call reply after listen int status = QlistenBeforeReply (q, messh, mess, maxsize) ; if (status == QSUCCESS) status = QreplyAfterListen (q, 0, 0, 0, 0, 0) ; else QreplyAfterListen (q, 0,0, 0,0,0) ; return (status) ,-
int QlistenBeforeReply (lpQHANDLE q, // Q handle returned by Qopen 0 ; lpMSGH messh, // Pointer to message header to fill char mess, // Pointer to message buffer to fill int max size) { // size of message buffer int objn, bnum, rtn, dsize, status NOT COMPLETE; IpSMBUF buf; .
if(q == NULL) FailC'Qlbr not passed handle"),- if (max size == 0) FailC'Qlbr not passed any message buffer") // When your Qopen (GETTING) you reserve buffers, so we want
// to wait on one becoming READY.
// When it is ready, we copy the data out.
Diag ( "Qlbr [-] : waiting for one of %d buffers to become ready ...", q->num_bu-._;
// Wait for a buffer rtn = WaitForMultipleObjects (q->num_bufs, q->readyh, FALSE, INFINITE) ; // objn = rtn - WAITJDBJECTJO ; if ((objn < 0) || (objn > q->num_bufs) )
Fail ("Qlbr [-] : WaitForMultipleObjects fails [%d]",rtn); bnum = q->bufs_found [objn] ,-
Diag ( "Qlbr [%d] : WaitForMultipleObjects got object %d mode=%d" , bnum, objn, q->ms buf = SMBUFADDR(bnum) ;
// Read the message out of the buffer dsize = min (max_size, buf->msgh. size) ,- memcpy (messh, &buf ->msgh, sizeof (MSGH) ) ; memcpy (mess, &buf->mdata, dsize) ; Status = QSUCCESS;
// Return without notifying the sender i.e. without releaing "done" // Qral will be called next to do that q->cur_objn = objn; // Save for QralO to use. Diag ( "Qlbr [%d] : returns" , bnum) ; return (status) ,-
int QreplyAfterListen ( lpQHANDLE q, // Handle returned by Qopen ( ) int mode , // Optional type of message int sub_mode , // Optional User defined type of essa char *mess, // Reply message to send int size, // Size of reply messsage lpMSGH mh) { // Optional message header int objn, bnum, status=QSUCCESS; IpSMBUF buf ;
if(!q) Fail ("Qral: not passed handle"); if (q->cur_objn == -1) Fail ("Qral called out of order")
// Retrieve handels objn = q->cur_objn; bnum = q->bufs_found [objn] ,- buf = SMBUFADDR (bnum) ; q->cur_objn = -1;
Diag ( "Qral [%d] object %d" , bnum, objn) ;
// Consturct the message header buf->msgh. size = size; if (mh) ( buf- >msgh. mode = mh->mode; buf->msgh. sub_mode = mh->sub_mode; // buf->msgh. size = mh->size; // removed 12/27/95 by derek, passed size sho buf->msgh. reply_smbuf = mh->reply_smbuf ; if (mode) buf->msgh.mode = mode; if (sub_mode) buf ->msgh. sub_mode = sub_mode,-
// Copy any message data if (buf->msgh. size = min (buf ->msgh. size, MAXMSGDATA) ) ( memcpy ( &huf - >mdata , mess , buf - >msgh . size) ,- } else strcpy (buf ->mdata, "") ; // Clear the whole buffer?
Diag ( "Qral [%d] : releases done %d" , bnum, objn) ,- buf->status = SMBUF_RETURN_MESS ; if ( [ReleaseSemaphore (q->doneh [objn] ,1,0) )
Warn ("Qral [%d] : ReleaseSemaphore done #%d" , bnum, GetLastError ()) ;
SHAREDATA (stat .gets) ++; // Statistics Diag ( "Qral [%d] : returns (%d) ", bnum, status) ; return (status) ;
}
////////////////////////////////////////////////////////////////////////////////
//
// Common routines and definitions used by OpenMQ
// ///////////////////////////////////////////////////////////////////////////// '
// Size of shared memory ttdefine LINESIZE 1024 ttdefine NAMESIZE 20 ttdefine ROUTNAME "c : \\q\\routing . txt " ttdefine PARMNAME "c: \\qWparms.txt" ttdefine MLOGNAME "c: \\qWqlogl.txt" ttdefine TLOGNAME "c: \\qWtranlog.txt" ttdefine SMEMNAME "Q/SHAREDMEMORY" ttdefine SMEMTABLE "Q/SHAREDTABLE" ttdefine MUTQOPEN "Q/QOPEN" ttdefine MUTFREFMT "Q/SMB_FREE_%d" ttdefine SEMRDYFMT "Q/SMB_READY_%d" ttdefine SEMDONFMT "Q/SMBJDONE_%d" ttdefine SEMACKFMT "Q/SMB_ACK_%d" ttdefine CLASSNAMES "classO classl class2 class3" ttdefine SMBUFADDR(X) (IpSMBUF) ((int) smjbase + (X ♦ sizeof (SMBUF) ) ttdefine MAXSMSIZE(X) sizeof (SMBUFH) + X sizeof (SMBUF) ; ttdefine BITSET(X,Y) ( (X & Y) == X) ttdefine MAXMSGDATA (MAXTXSIZE - sizeof (MSGH) ) ttdefine SHAREDATA (X) (smjbase->X) ttdefine MAXTXSIZE 8192 ttdefine MAXNSMBUF 32 ttdefine MAXRTSIZE ((MAXTXSIZE - sizeof (MSGH) ) - 10) // bytes ttdefine MAXFOLENT 8 ttdefine FD_SETSIZE 64 / Number of sockets / //ttdefine RTROOT (lpRT) ((IpSMBUFH) smjbase) ->RT ttdefine RTROOT (lpRT) sm_base->RT [smjbase- >rt_pmgpong]
// Return codes ttdefine QSUCCESS_FAILOVER IL ttdefine QSUCCESS 2L ttdefine NO_SUCH_QUEUE 11L ttdefine NO_MORE_SHARED_MEM 12L ttdefine NO_ACK 13L ttdefine NOT_COMPLETE 14L ttdefine WRONG_SMBUF_STATUS 15L ttdefine QFAIL 16L ttdefine QTOOBIGMESS 17L ttdefine NOJQNETD 18L ttdefine QMODE MISSMATCH 19L
// Message Modes or message Types ttdefine PUT_MODE 2L ttdefine GET_MODE 3L ttdefine REQUEST_MODE 4L ttdefine ACK_MODE 8L ttdefine NACK MODE 9L ttdefine COMMIT MODE 10L 000181 ttdefine ABORT_MODE 11L ttdefine ADMINREQ_MODE 20L ttdefine ADMINREP_MODE 21L ttdefine QNETDREQ_MODE 30L ttdefine QNETDREP MODE 31L
// Message sub_modes used by QNETD ttdefine QNETD_TRAN__INQ 2L ttdefine QNETD_RT_BROADCAST 3L ttdefine QNETD_BUF_STATUS 4L
// Message sub_modes used by QUE servers ttdefine SUB_MODE_OK ttdefine SUB_MODE_EMPTY 11L ttdefine SUB_MODE_FULL 12L ttdefine SUB_MODE_DISABLED 13L ttdefine SUB_MODE_INV_INDX 14L // invalid que entry number ttdefine SUB_MODE_INV_TID 15L // invalid TID for pending list search ttdefine SUB MODE BAD REQ 16L //
// Transactio inquiry msg modes ttdefine Q_COMMIT COMMIT_MODE ttdefine Q_ABORT ABORT_MODE ttdefine Q_INPROGRESS 12L ttdefine Q WRONGHOST 13L
// Shared Memory Buffer Status Codes ttdefine SMBUFJEMPTY OL ttdefine SMBUF_SEND_MESS IL ttdefine SMBUF_RETURN_MESS 2L ttdefine SMBUF_RETURN_FAIL 5L ttdefine SMBUF_GET_MESS 10L ttdefine SMBUF_GOT_MESS 11L ttdefine SMBUF SEND REMOTE 100L
// Qopen & Qput & Qget flags ttdefine Q_LOG (OxOOOOOOOlL) // Log this message (not required if T ttdefine QJTRACE (OX00000002L) // Generate trace entries for this mes ttdefine Q_ASYNC (0X00000004L) // Dont wait for the message to get to ttdefine Q_FAILOVER (0X00000008L) // Enable failover (if its defined in ttdefine QJTRAN (OxOOOOOOlOL) // Use two phase commit ttdefine QJTRANJBEGIN (OX00000030L) // Start the tran ttdefine QJTRANJEND (0X00000050L) // End the tran (commit) ttdefine Q TRAN SINGLE (OxOOOOOOFOL) // Both start and end
// Includes 11111111111111111111111111111111111111111111111111111111111111111111 ttinclude <stdlib.h> // for exitO call ttinclude <malloc.h> // for malloc 0 call ttinclude <stdio.h> // for printf () call ttinclude <windows.h> // HANDLE definition ttinclude <time.h> // for mid time () //ttinclude <windowsx.h> // ListBox_AddString
// structures 111111111111111111111111111111111111111111111111111111111111111111 typedef struct mid // Message header mt host ; // IP of sender int tid ; // mcremnets on each tran. 0= not transactional mt uid ; // unique ID for each msg entry
} MID, *lpMID;
typedef struct mlist { // List of MIDs struct mlist *next; MID mid;
} MLIST, *lpMLIST;
typedef struct msgh { // Message header mt type_codιng; // Header version, and machine coding format short mode ,- // Message type (Putting or Getting) short sub mode ,- // User defined sub_mode mt flags; // 32 bit message flags t me t time; // Time (set but not used)
MID mid; // Last Unique message id (struct?) t to_node,- // ip target mt to_port, // qnetd port on the target or sm buffer # mt to smbuf; // Shared memory buffer of receiver mt from smbuf; // Shared memory buffer of sender i.e QNETDttl int reply_smbuf ,- // Shared memory buffer for reply messages char to server [NAMESIZE] ,- // Physical queue server name char to_logιcal [NAMESIZE] ; // Logical queue name int size; // size of the message
} MSGH, ♦lpMSGH, typedef struct qhandle { // Que Handle struct qhandle ♦next; // Next handle if in chain
MSGH msgh,- // Prototype message header tιme_t open_tιme; // Time the open ( ) was made int base_flags; // Flags to be used m all ops short cur_obηn; // Current object (buff) number int tιme_out ; // minimum time-out on this node short rt_rev; // Rev of the Routing Table that was used short num_bufs; // Number of buffers where service was found short bufs_found[64] ; // Buffers where the service was found
HANDLE freeh[64] ; // Handles for the "free" mutex for each buffer
HANDLE readyh [64] ,- // ??notset? Handles for the "ready" semephore for ea
HANDLE doneh [64] ,- // ??notset? Handles for the "done" semephore for eac } QHANDLE, *lpQHANDLE; typedef struct smobjs { // Sync Obj for 1 Shared Memory Buffer
HANDLE freeh; // Handle for the "free" mutex for each buffer
HANDLE readyh; // Handle for the "ready" semephore for each buffer
HANDLE doneh; // Handle for the "done" semephore for each buffer
HANDLE ackh; // Handle for the "ack" semephore for each buffer } SMOBJS, *lpSM0BJS; typedef struct smbuf { // Shared memory buffers char name [NAMESIZE] ,- short status; short sub_status; // Currently not used!
MSGH msgh; char mdata [MAXMSGDATA] ; } SMBUF, *IpSMBUF; typedef struct aps // any app specific shared data int app_num; // this is not accessed by OpenMQ int appdatl ,- // int appdat2 ,- // int appdat3 ; //
} APS, *lpAPS; // typedef struct stat { int opens , openrep , closes ,- int puts, gets; int tx, rx; int commit , abort ; int warn, fail ;
} STAT, *lpSTAT; typedef struct fol ( char name [NAMESIZE] // Logical queue name int puts, gets, // Operations that fail int ip; // Addres to fail to
} FOL, lpFOL,-
/* typedef struct st ( // QNETD Sockets Table struct st next; // int ip ,- // int port ,- // SOCKET s ; // SOCKET def requires sock. lib
} ST, *lpST;
*/
// Shared memory
// typedef struct smbufh ( // Shared memory header (global data area) int tran id; // Current unique tran id for this node. int unique_id; // Current unique message id for this node. int nostip , // This nodes IP short diag; // Diagnostics On/Off short nsbuf ; // Number of shared buffers int time_out ; // minimal timeout on this node short failed_servers ,- // number of failures detected int time; // now (watchdog's clock) int start_time; // time shared mem was initialized int rt_rev; // rev of last RT update (MINOR) int rt_ver ; // version of last RT received (MAJOR) int rt_pingpong; // RT Buffer to use int tmpl ,- // not used int tmp2 ; // not used int tmp3 ; // not used
APS ap; // not used (used by oentry)
STAT stat ,- // statistics char hostname [NAMESIZE] ,- // Hostname
// int sockets // Number of active sockets
// ST ST [MAXFOLENT] ; // Socket table
FOL FO [MAXFOLENT] ; // Fail over list char RT[2] [MAXRTSIZE] ; // Routing table
} SMBUFH , *lpSMBUFH; // Routing table // typedef struct rt { // Routing Table in shared memory int ip ,- // int qnetd_port ,- // int next_offset ,- // int ntype_index,- // int apps_index,- // char s [4] ; // node\0ntype\0apps\0 <<More than 4 char>>
} RT, *lpRT;
// Global data //////////////////////////////////////////////////////////////// // C++ does not allow 2nd define of variables, ttifndef QJLIB ttdefine QJLIB
IpSMBUFH sm_base; // Base address of shared memory segment // lpQHANDLE FLroot; // Linked list of (any) failed servers char AskAnswer [LINESIZE] // Defined in prin . c ttendif
// Routines //////////////////////////////////////////////////////////////////// ttifdef CPP extern "C"
{ ttendif void Say ( ) ; // Dont check any parameters void FailO // Dont check parameters void Warn ( ) // Dont check parameters void DiagO // Dont check parameters char *Ask() // Dont check parameters //void Mlogtchar *msg) ;
// ttdefine Diag if (SHAREDATA (diag) ) Say Made a call so "if" doesnt mess up int ReserveSharedBuffer ( int seqno, char *bname, int bstatus,
IpSMOBJS sync) ; int UnReserveSharedBuffer (int bnum)
lpQHANDLE Qopen ( char *que_name // Queue name (logical) short mode, // Predefined Mode (PUT_MODE/GET_MODE) short sub_mode , // Userdefined sub_mode int flags, // Optional Flags (input) int ♦status, // Optional detailed failure code (out int buffers, // Optional number of buffers to make int index) ,- // Optional index of server to be open
lpQHANDLE QopenReply (lpQHANDLE q, // Optional existing q handle to be re lpMSGH mh, // Message to reply to int flags, // Optional Flags for Qopen () char *name , // Optional server name nnn_85 mt ♦status) , // Optional detailed status code t QreOpen ( lpQHANDLE q ) , // Get new buffer and routing info int Qclose ( lpQHANDLE *ppq< // Optional Queue handle OR char *bname) , // Optional name must be specifed int Qput ( lpQHANDLE q- // Q handle returned by Qopen () , short mode, // Optional mode for this put, short sub_mode , // Optional sub_mode for this put, int flags, // Optional Extra flags for this Put ( ) int size, // Number of bytes to transfer char *buffer) , // Optional Buffer that holds the mess mt QsendAndReireive (lpQHANDLE q, // Q handle returned by Qopen () , mt mode, // Optional Mode for this put int submode , // Optional SubMode for this put mt putflags, // Optional flags for this Put, nt putsize, // Number of bytes to transfer char *putbuf , // Optional Buffer that holds the mess int maxgetsize // Optional size of get buffer char *getbuf , // Optional buffer fill with message d int *gotsιze, // Optional number of bytes filled lpMSGH gothead) , // Optional got message header
int Qget( lpQHANDLE - // Q handle returned by Qopen () , lpMSGH messh, // Pointer to message header to fil char *mess, // Pointer to message buffer to fill int maxsize // size of message buffer
t QlistenBeforeReply (lpQHANDLE q, // Q handle returned by Qopen 0 , lpMSGH messh, // Pointer to message header to fill char *mess, // Pointer to message buffer to fill int max s ze) // size of message buffer
mt QreplyAfterListen { lpQHANDLE q, // Handle returned by Qopen () mt mode, // Optional type of message mt sub_mode , // Optional User defined type of messa char ♦mess, // Reply message to send mt size , // Size of reply esssage lpMSGH mh) , // Optional message header
void Qcommit ( mt action) , // Commit or abort t F ndSMBuffers ( lpQHANDLE q, mt targetsip, // Local or Remote IP char *physιcal name, // Blank if not used mt target_smbuf) , // -1 if not used
IpSMBUFH AttachSharedMemory , // Used by graphic apps vo d SetWmPtr(HWND WinPtrX) , // Printing to GUI output void ForcedBufferReset ( t bnum, // Optional Buffer number (-1 = not us lpQHANDLE q, // Optional Queue Handle int objn) ; // Optional objet number in Queue Hand
ttifdef CPP
} ttendif
ttifdef QLIB // Routines that only QLIB uses (Not API)
IpRT ServerByName2 (IpRT rtp, char *name, int index, char physical)
void TLadd (lpQHANDLE q) ; // From tran.c void SetTID pMID m, int flags);
IpRT RTBylPdnt IP) ; void PrintRT pRT r,char s) ; ttendif
//////////////////////////////////////////////////////////////////////////////// // Qnetd.h //////////////////////////////////////////////////////////////////////////////// ttinclude <winsock.h>
// Structures ////////////////////////////////////////////////////////////////// typedef struct st { // QNETD Sockets Table struct st next; // int ip; // int port; //
SOCKET s; // SOCKET def requires sock. lib } ST, *lpST;
// Routines ////////////////////////////////////////////////////////////////////
//void ReadRTO; // QLIB call move it to qnetd?
LPVOID SharedMemlnit (int nsbuf);
DWORD ListenConn ( ) ;
DWORD ListenSMBuff () ;
DWORD Wa chDog ( ) ;
int SendRemoteMess (IpSMBUF buf, int pass); IpST AddSocketToTable (SOCKET sock, SOCKADDR_IN *sa)
IpRT RTByName (char *name) ; //QLIB call used by QNETD/tcp.c int ResolveTran pMID MID) //QLIB call used by QNETD to return admin messa void ReadParms (int *nsbuf) ,- int Str2Port (char *str) ,-
/* + *
** Copyrigh (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED. UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
** OR DISCLOSURE.
**
** THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
** TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
** OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
** OpenMQ
* * Module : qopen . c
** Author: Derek Schwenke 9/8/95
**
** Qopen/Qclose API calls
*/
ttinclude "qlib.h" ttinclude "rt.h" extern IpSMBUFH smjbase;
int FindSMBuffers ( lpQHANDLE q, int targetsip, // Local or Remote IP char *physical_name, // If local, name must be set int target_smbuf ) j // -1 if not used int i = 0 ,- int found = 0 ,- char searchfor [NAMESIZE] // Buffer name char freen [NAMESIZE] ; // Syncronization object name char readyn [NAMESIZE] ; // Syncronization object name char donen [NAMESIZE] ; // Syncronization object name
// This routine finds the buffers to use ON THE LOCAL NODE, to // communicate. If the targetsip is remote, then it returns // the buffers that QNETD will listen to.
// Messages can be sent to logical services
// Reply messages are sent to specific smbuffers if (SHAREDATA (hostip) == targetsip) ( // then its local strcpy (searchfor ,physical_name) ,- if (target_smbuf != -1) i = target_smbuf ; } else { // its not local
Diag ("The physical server of %s is not local I " ,physical_name) strcpy (searchfor, "QNETD") ;
q->num_bufs = 0; while (i < SHAREDATA (nsbuf) ) { IpSMBUF bp = SMBUFADDR ( i ) ; if (( I strcmp (bp->name, searchfor) ) | | (i==target_smbuf) ) // Found a buffer // Get a handle for this buffer // Pack the handle into arrays so we can wait on any one of them.
sprintf (freen, MU.TFREFMT, i) ; sprintf (readyn, SEMRDYFMT, i) ; sprintf (donen, SEMDONFMT, i) ; if ( I (q->freeh[q->num_bufs] = OpenMutex( SYNCHRONIZE, FALSE, freen)
FailC'Could not OpenMutex %s Error=%d" , freen, GetLastError ()) ; if ( I (q->readyh[q->num_bufs] = OpenSemaphore (SEMAPHORE_MODIFY_STATE | £>_
FailC'Could not OpenSemaphore %s Error=%d" , readyn, GetLastError ()) ; if ( I (q->doneh[q->num_bufs] = OpenSemaphore (SEMAPHORE_MODIFY_STATE | SYN
Fail("Could not OpenSemaphore %s Error=%d" , donen, GetLastError ()) ; q->bufs_found [q->num_bufs++] = i ,-
Diag ( " Buffer %d [%s] found ", q- >num_bufs, searchfor) ,- if (q->num bufs == 64) continue; // Stop looking
} if (i++ == target_smbuf ) i = SHAREDATA (nsbuf ) ,- // We are done with just o
} if (q->num_bufs) {
Diag ("Qopen [%s] found %d buffers" , searchfor, q->num_bufs) ,- } else {
Warn ( "Qopen [%s] No such server No buffers were ound! ", searchfor) ;
return (q- >numjDufs) ,-
lpQHANDLE Qopen ( char que name // Queue name (logical) short mode, // Predefined Mode (PUT_MODE/GET_MODE) short sub_mode , // Userdefined sub_mode int flags , // Optional Flags (input) int status , // Optional detailed failure code ( int buffers, // Optional number of buffers to make int index) { // Optional index of server to be open
// When called for PUT_M0DE, just look for existing SMBUFers using this queue n // When called for GET_MODE, reserve a new set of buffers under the name int rtn, found = 0, stat = QSUCCESS; lpQHANDLE q = (lpQHANDLE) malloc (sizeof (QHANDLE) ) ;
IpRT rt=NULL; char physical_name [NAMESIZE] ;
HANDLE mutex;
// Attach to shared memory if ( !sm_base) { if(!( smjoase = AttachSharedMemory 0 ))
status = NOJQNETD; return (0) ;
Diag ( "Qopen (%s) opens mutex" , que_name) ,- if (I (mutex = OpenMutex (MUTEX_ALL_ACCESS , FALSE, MUTQOPEN) ) ) // Ser Fail ("Qopen (%s) : Cant OpenMutex %s %d" ,que_name, GetLastError ()) ,- // Fails if ( (rtn = WaitForSingleObject (mutex, INFINITE) ) ! = WAIT_OBJECT_0 )
Fail ("Qopen (%s) : Failed while waiting for mutex %s %d" , que_name , &MUTQOPEN
if (lq)
Fail ( "Qopen (%s) malloc error" , que__name) ,- // memset (q, 0, sizeof (QHANDLE) ) ;
// Find this queue in the RT // If gettting look for servers on this node ^n
if (mode == GET_MODE) { q->msgh to_node = SHAREDATA (hostip) , q->msgh. to_port = 0 ,- strcpy (physιcal_name, que_name) ,
// rt = ServerByName2 (RTBylP (SHAREDATA (hostip) ) ,que_name, index, physical na // } else { // PUT_MODE rt = ServerByName2 (RTROOT, que_name, index, physιcal_name) ; if (Irt) // It's not in the routing table but check the local node anyway if (FindSMBuf fers (q, SHAREDATA(hostιp) ,que_name, -1) ) { rt = RTBylP (SHAREDATA (hostip) ) ; // Return this node strcpy (physιcal_name, que_name) ,
// Assign values from RT into handle if (rt || mode == GETJMODE) { if (rt) ( q->msgh . to_node = rt->ιp; q->msgh. to_port = rt->qnetd_por , strcpy (q->msgh to_server , hysιcal_name) ;
q->msgh. type_codmg = 1; q->msgh. flags = 0; q->msgh.mode = mode ; q->msgh.sub mode = sub mode ; q- >msgh . mid . host = SHAREDATA (hostip q- >msgh . mid . tid = 0; q->msgh. time = 0; q->msgh.to smbuf = -1; strcpy (q- >msgh . to_logical, que name); q->msgh.from smbuf = 0; q->msgh. size = 0; q->base_f lags flags; // Flags used for all future access q->cur_ob}n -1; // SMBUF number being used. q->num_bufs 0 ; // number of buffers found. q->next NULL; // Pointer to chain of handles q->open_tιme SHAREDATA (time) ; //time (&q->openJtιme) ,-
if (mode == GET_MODE) { q->tιme_out = INFINITE; // 0x7FFFFFFF; // 24 days } else { q->tιme out = SHAREDATA (tιme_out) ;
} if (mode == PUT_MODE) {
// Dont allocate, just find a list of existing buffers ιf( ' FindSMBuffers (q, q->msgh. to_node,physιcal_name, -1) )
stat = NO_SUCH_QUEUE ; } else if (mode == GET_MODE) ( // make a set of new buffers SMOBJS sync ; int i,b, seqno = 0 ; int dontcheck = (buffers == -1) ; // Dont check for stale existing bu^e
// Reserve Shared buffers if (buffers == -1) seqno = 999; if (buffers < 1) buffers = 1 ,- if (buffers > SHAREDATA (nsbuf) - 1) buffers = SHAREDATA (nsbuf ) - 1;
Diag ( "Qopen (%s) for GET_MODE : reserving %d buffers" , que_name, buffers) ; for ( i = 0 ; i < buffers ; i++ ) ( if (-1 != (b = ReserveSharedBuffer ( seqno++, physical_name , SMBUF_EMPTY, ksync) )) { q->bufs_found [i] = b; q->num_bufs++ ; q->freeh[i] = sync.freeh; q->readyh[i] = sync . eadyh; q->doneh[i] = sync. doneh; } else (
Say ("Qopen (%s) for GE JMODE : Failed, got %d of %d buffers" , que_na if (i==0) stat = NO_MORE_SHARED_MEM; break;
Diag ( "Qopen (%s) for GET_MODE : reserved %d buffers" , que_name, buffers) ; } // end of PUTTING or GETTING else ( // No rt route was found PrintRT (RTROOT, " " ) ; stat = NO_SUCH_QUEUE ; Warn ( "Qopen ( %s) NO_SUCHJQUEUE" , que_name) ,-
} if (stat != QSUCCESS) { free (q) ; q = NULL; }
ReleaseMutex (mutex) ; // Mutex on all QOpen ( ) calls if (status) *status = stat; return (q) ;
int Qclose ( lpQHANDLE ppq, // Optional Queue handle OR char ♦bname) { // Optional name must be specifed lpQHANDLE qp; int i ;
// Attach to shared memory if ( !sm_base) { if(!( smjoase = AttachSharedMe or ( ) )) return (NO QNETD) ,-
00019Z
if (bname) (
Diag ( "Qclose (%s) by name ", bname ) ,- for (i = 0; i < SHAREDATA (nsbuf ) ; i++) // All buffers if ( I strcmp ( (SMBUFADDR ( i ) ) - >name, bname) ) UnReserveSharedBuffer (i) ;
} else if (ppq) { if (qp = *ppq) { if (qp->msgh.mode == GET_MODE) ( // Release any buffers .. perhaps num
Diag ( "Qclose (%s) by handel", (SMBUFADDR (qp- >bufs_found [0] )) ->name) ; for (i = 0; i < qp->num_bufs ; i++) if (UnReserveSharedBuffer (qp->bufs found [i])),-
} free (qp) ,-
ppq = NULL;
r 1etu'rn (QSUCCESS) ,-
// Used for putting messages back to the sender (use if the sender is listeni- * lpQHANDLE QopenReply ( lpQHANDLE q, // Optional existing q handle to be re lpMSGH mh, // Message to reply to int flags, // Optional Flags for Qopen ( ) char name, // Optional server name int status) { // Optional detailed status code int stat = QSUCCESS, bnum;
if ( !sm_base) ( // This cant happen, you must Qopen first, if ( I ( smjnase = AttachSharedMemory () )) if (status) ♦status = NOJQNETD; return (0) ,- } if Oq) { q = (lpQHANDLE) malloc (sizeof (QHANDLE) ) ; if (!q) Fail ("QopenReply Malloc error"),- memset (q, 0, sizeof (QHANDLE) ) ; } if (mh) {
// Construct que handle from messge header q->msgh. ype_coding = 1; q->msgh.mode = PUT_MODE; q- >msgh . sub_mode = 0 ; q->msgh. flags = flags; q->msgh. mid. host = SHAREDATA (hostip) ;
q->msgh.mid. id = 0 ; q->msgh.time = 0 ; q- >msgh . to_node = mh->mid.host ; q- >msgh. to_port = 0; q->msgh.to smbuf = mh->reply_smbuf ; if (name) strcpy (q- >msgh. to_server , name) ; strcpy (q->msgh. tojlogical, name) ,- q- >msgh . from_smbuf = 0; q- >msgh . reply_smbuf = 0; q->msgh. size = 0; q->base_flags = flags; q->cur_objn = -1; q->num_bufs = 0; q->next = NULL; // Pointer to chain of handles q- >open_time = SHAREDATA (time) ; q->time_out = SHAREDATA ( time out);
//time (&q->open_time) ;
// Get a list of buffers for this service bnum = mh- >reply_smbuf ; if (name ) if ( I strcmp (name, "QNETD" ) ) bnum = 0; if( I FindSMBuffers (q, mh->mid. host , "" , bnum) ) stat = NO_SUCH_QUEUE ;
} else {
Say ( "QopenReply ( ) was not passed a message header") Stat = NO SUCH QUEUE;
} if (status) status = stat; if (stat == QSUCCESS) return(q); free (q) ,- return (0) ,-
int QreOpen ( lpQHANDLE q) { // Existing q handle to be replaced IpRT rt=NULL; if (!q) return (NO_SUCH_QUEUE) ,- if (q->msgh.mode == GET_MODE) return (QMODE_MISSMATCH) ,- rt = RTByService (q) ; if (Irt) { // It's not in the routing table but check the local node anyway if (SMByName (q->msgh. to_logical) ) { rt = RTBylP (SHAREDATA (hostip) ) ; // Return this node strcpy (q- >msgh . to_server , q- >msgh . tojlogical ) ;
// Assign values from RT into handle if (rt) ( q->msgh. to_node = rt->ip; q->msgh. to_port = rt->qnetd_port ,-
// Get a list of buffers for this service if ( I FindSMBuffers (q,q->msgh. to_node, q- msgh. to_server, -1) ) // q- >msgh . to ..s return (NO_SUCH_QUEUE) ; return (0) ; }
int ApClose ( lpQHANDLE ap ) free (ap) ; return (QSUCCESS) ,- }
/* **
* Copyright (C) 1995 MITSUBISHI ELECTRIC ITA ALL RIGHTS RESERVED
♦♦ UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
♦♦ LAWS OF THE UNITED STATES USE OF A COPYRIGHT NOTICE
♦♦ IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
♦♦ OR DISCLOSURE
**
♦♦ THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
* TRADE SECRETS OF MITSUBISHI ELECTRIC ITA USE, DISCLOSURE,
♦♦ OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA
* *
♦♦ OpenMQ
* Module qprint c
Author Derek Schwenke 9/8/95
**
* ♦ Printing routines used by OpenMQ * / ttinclude "qlib h" ttinclude wιndowsx h>
//ttdefme Diag (X) if (diag) (Say(X),}
// Global Data ///////////////////////////////////////////////////////////////// FILE MLOG = NULL, // Message Log File
// HANDLE MLOG = NULL, // Message Log File
HWND LogWm, // Global data - Handle for printing to window t LogWιnIndex=0 , // Index of last lines written to the log in ,
// extern mt diag, void SetWmPtr (HWND WinPtr) { LogWm = W Ptr, ListBoxJResetContent (LogWm) , LιstBox_SetCurSel (LogWin, LogWmIndex++) ,
// Routines 11111111111111111111111111111111111111111111111111111111111111111111 void Mlog(char ♦msg) { // Log to a file
// t len, 1,3,
// char line [LINESIZE] , ttifdef GUI
//char lme2 [LINESIZE] , //TRACE (msg) , // LιstBox_InsertStnng LιstBox_AddStnng (LogWm , msg) , LιstBox_SetCurSel (LogWin , LogWmIndex++) , ttendif if ( • MLOG ) { if ((MLOG = fopen (MLOGNAME, "a") ) == NULL )
/♦ if ( NULL == ( MLOG = CreateFile ( MLOGNAME , GENERICJWRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_RE D, 0 , OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL, 0))) //FILE_FLAG_WRITE_THROUGH
*/ ' • printf ("ERROR CAN NOT OPEN LOG FILE %s" , &MLOGNAME) ,
into a \r\n
Figure imgf000199_0001
sprintf (line, "%s\r\n" ,msg) ,
WriteFile (MLOG, line, strlen (line) , &len,NULL) ,
2 , a3 , a4 ; , a5 , a6 )
Figure imgf000199_0002
ttendif
Figure imgf000199_0003
// char AskAnswer [LINESIZE] , chair Ask( char msg, void ♦al, void a2, void *a3, void a4, void a5, void *a6) { char line [LINESIZE] , sprintf (line, msg, al,a2,a3,a4,a5,a6) , strcat (line, " >") , ttifndef GUI prmtf ( " %s " , line ) , ttendif ttif wer) ,
Figure imgf000199_0004
Mlog (AskAnswer) , 1)1)1) l" '
return (AskAnswer)
void Diag ( char msg void al, void a2, void a3, void a4, void a5, void a6) i f ( SHAREDATA (diag) )
Say (msg, al, a2, a3 , a4,a5,a6) ;
d Warn ( char msg, void al, void a2,
char line if(sm bas
Figure imgf000200_0001
(sta .warn) ++ ; sprintf (line, "\nWARNING: %s\n" ,msg) ; Say (line , al , a2 , a3 , a4 , a5 , a6 ) ;
) void Fail ( char msg, void al, void a2,
char line char bli
Figure imgf000200_0002
; int r=0; if (smjDase) SHAREDATA (stat . fail) ++; sprintf (line, "\nError: %s\n",msg) ; Say (line , al , a2 , a3 , a4 , a5 , a6 ) ; sprintf (line, "\nError: %s\nClick 'Retry' or 'Ignore' to continue" , msg) ,- sprintf (mbline, line, al, a2 , a3 , a4 , a5 , a6) ,- r = MessageBox(NULL, mbline, "FATAL ERROR DETECTED" , MB_ICONSTOP | MB_ABORTRETRYIG if ( r == IDABORT ) (
Say("Bye\n" ,0,0,0,0,0,0) ;
ExitThread(O) ; } else
Say ("CONTINUES AFTER FATAL ERROR" , 0 , 0 , 0 , 0 , 0 , 0) ;
Ask ("Type any character to continue or return to exit" , 0, 0, 0, 0, 0, 0) ; if (strlen (AskAnswer) ) (
Say ( " CONTINUES AFTER FATAL ERROR" ,0,0,0,0,0,0);
} else ( 000198
Say("Bye\n" ,0,0,0,0,0,0) ; //ttifndef GUI
// exιt(0) ;
ExitThread(O) ,- // Try this //ttendif
} */ }
/* **
** Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED
* * UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
** LAWS OF THE UNITED STATES USE OF A COPYRIGHT NOTICE
** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
** OR DISCLOSURE.
**
** THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
** TRADE SECRETS OF MITSUBISHI ELECTRIC ITA USE, DISCLOSURE,
** OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
** OpenMQ
Module . qput . c
* * Author . Derek Schwenke 9/8/95 */ ttinclude " qlib . h " ttinclude " rt h " extern IpSMBUFH s joase ; //extern" lpQHANDLE FLroo ,
III ii iiiiiiiiiiuiiiiiiiiiiiiiiiiiinm nun iiiiiuiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiuiimiiiiiimmmimiuiiiiiumiiimiimum nt Qput ( lpQHANDLE q. 1/ Q handle returned by Qopen () , short mode, // Optional mode for this put; short sub mode // Optional sub_mode for this put; int flags , // Extra flags for this Put ( ) , t size, // Number of bytes to transfer char ♦buffer) { // Buffer that holds the messages return (QsendAndReceive (q, mode, sub_mode , flags, size, buffer, 0,0,0,0)),
int QsendAndReceive (lpQHANDLE q, // Q handle returned by Qopen ( ) ; mt mode, // Optional Mode for this put mt sub_mode , // Optional SubMode for this put int putflags, // Optional flags for this Put; int putsize, // Number of bytes to transfer char putbuf , // Buffer that holds the messages. int maxgetsize , // Optional size of get buffer char ♦getbuf , // Optional buffer fill with message data t gotsize, // Optional number of bytes filled. lpMSGH gothead) { // Optional got message header. int objn, bnum, rtn, status = NOT_COMPLETE , maxpass, pass = 0,ms,
IpSMBUF buf;
if (q == NULL) (
WarnC'Qsar [-] • passed NULL handle"), return (NO SUCH QUEUE);
if (q->num_bufs == 0) { if (Qreθpen(q) != 0) (
WarnC'Qsar [-] : passed bad handle, no buffers after QreOpen ( ) " ) ; return (NO_SUCHJQUEUE) ; 000 0
if (putsize > MAXMSGDATA) (
Warn ( "Qsar [-] : Message data too big %d", putsize) retur (QTOOBIGMESS) ,
q->msgh flags = q- >base_flags | putflags, if (q->msgh. flags & Q_FAILOVER) maxpass = 3, else maxpass = 1 ;
while (pass < maxpass) { // loop "contme" if error "break" if good if (pass) MarkFailedServer (q) ; if (q->rt_rev < SHAREDATA ( rt_rev) ) UpdateHandle (q) , pass++ ,
// Wait for a buffer
Diag ( "Qsar [-] : waiting for one of %d buffers to become free " , q- >num buf if (putflags) Diag ( "Qsar [-] : flags = %p" , putflags) , * ~ rtn = WaitForMultipleObjects (q- >num_bu s , q->freeh, FALSE, q- >tιme_out-500) ; objn = rtn - WAITJDBJECTJO ; if ( (objn < 0 ) I I ( objn > q->numjDufs) ) ( t abn = rtn - WAIT_ABANDONED_0 , if (q->num_bufs == 0) {
Warn ( "Qsar [-] : Bad handle: has no buffers"),- continue; } else if (rtn == WAITJTIMEOUT) ( WarnC'Qsar [-] : timeout") ; continue,- } else if ( (abn >= 0 ) && (abn < q->num_bufs) ) ( Warn ( "Qsar [-] : Waiting on abandoned obj %d",abn); continue;
}
Fail ("Qsar [-] : WaitForMultipleObjects fails [%d] on %d objects" , rtn, q-> continue ;
// Should report some error here bnum = q->bufs_found [objn] , buf = SMBUFADD (bnum) ;
// Diag ( "Qsar [%d=%s] : WaitForMultipleObjects got object %d" , bnum, buf ->name
// Safty check the identy of the buffer if (*q->msgh to_server) // if you know the name ("reply msgs only know the if (strcmp (q->msgh. to_server,buf ->name) ) if( 0 != strncmp (buf ->name, "QNETD" ,4) ) (
Warn ( "Qsar [%d=%s] : Stale handle. Wanted [%s] got [%s]", bnum, buf- >name , q- >msgh. to_server, buf- >name) ,-
ForcedBufferReset (-l,q,objn) ,
// Maybe re-open here?
Qreθpen(q); 000201
continue; }
// Transfer the data to the buffer memcpy (&buf ->msgh, &q->msgh, sizeof (MSGH) ) ; memcpy (&buf - >mdata, putbuf , putsize) , buf ->msgh. size = putsize, buf ->msgh . flags = buf ->msgh . flags | putflags; buf->status = SMBUF_SEND_MESS ;
SetTID (&buf ->msgh.mιd,buf - >msgh flags), // Set uid and not timed buf ->msgh. time = SHAREDATA (time) ,
if (mode) buf ->msgh. mode = mode, // Else use default from Qope if (sub_mode) buf - >msgh. sub_mode = sub_mode; // Else use default from Qope
// Notify the reciver
Diag ( "Qsar [%d=%s] . ReleaseSemaphore ready object %d starts mode=%d", bnum, buf- >name , objn, buf ->msgh. mode) , if ( 'ReleaseSemaphore (q->readyh [objn] , 1, NULL) ) {
Warn ( "Qsar [%d=%s] : ReleaseSemaphore ready failed handle %p tt d", bnum, buf ->name, q- >readyh [objn] , GetLastError ( ) ) ,
ForcedBufferReset (-l,q, objn) , status = QFAIL; // How to recover here7 }
// Wait for an answer if (buf ->msgh. to_node == SHAREDATA (hostip ) ) //leave time for remote to ms = q->tιme_out, // Local should be faster else ms = q->tιme_out + (q->tιme_out) /4 , // Remote is slower
Diag ( "Qsar [%d=%s] : Waiting for done object %d starts %d ms", bnum, buf ->name, objn,ms); if ((rtn = WaitForSingleObject (q->doneh [objn] ,ms) ) != WAITJOBJECTJύ ) ( if (rtn == WAITJTIMEOUT)
WarnC'Qsar [%d=%s] : WaitForSingleObject WAITJTIMEOUT after %d ms",bnu else
Warn ("Qsar [%d=%s] : WaitForSingleObject GetLastError = %d" , bnum, buf -> status = QFAIL; // Add new desciptive status code here''
ForcedBufferReset (-l,q, ob n) ; continue;
// Check the answer if (buf->status I- SMBUF_RETURN_MESS) {
WarnC'Qsar [%d=%s] : GOT A BAD BUFFER STATUS [%d] ", bnum, buf ->name, buf ->=t if (buf->status == SMBUF_RETURN_FAIL) status = QFAIL; else status = WRONG SMBUF_STATUS ,
ForcedBufferReset (-l,q, objn) ,- continue ,-
if (pass == 1) status = QSUCCESS; else status = QSUCCESS_FAILOVER;
// Get the reply's data if (getbuf && maxgetsize) ( int gotsz = min (maxgetsize, buf->msgh. size) ; if (gotsize) gotsize = gotsz ; memcpy (getbuf, &buf ->mdata, gotsz) ; } if (gothead) { // if the caller wants to see the header, copy it. memcpy (gothead, &buf ->msgh, sizeof (MSGH) ) ; }
// release the buffer if ( IReleaseMutex (q->freeh [objn] ) )
Warn ( "Qsar [%d=%s] : ReleaseMutex object %d failed #%d", bnum, buf ->name, objn, GetLastError () ) ,-
// If it's transactional, add to the open transaction list
// Perhaps the single tran case can be optimised not to reget the buffer? if (putflags & QJTRAN) TLadd ( q ) ;
// If it's the end of a transaction, then COMMIT if ( (putflags & Q_TRAN_END) == Q_TRAN_END) Qcommit (Q_COMMIT) ; // API call break; // We got this far, so it must have not failed. } // Loop 3 attempts to send if (status <= QSUCCESS) SHAREDATA (stat .puts) ++ ; return (status) ,-
/*
**
* * Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
* * UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT ** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE ** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION ** OR DISCLOSURE. **
THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* * EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
* * ** OpenMQ + * Module: routab.c
Author: Derek Schwenke 9/8/95
** Routing table funtions */
ttinclude "qlib.h" ttinclude "qnetd.h" ttinclude "rt.h" ttinclude <string.h> ttinclude <ctype.h>
int str2ip(char ♦str) ( int ipl, ip2 , ip3 , ip4 ; if ( 4 != sscanf (str, "%d. %d. %d. %d" , ϋipl, &ip2,&ip3, &ip4) ) // Perhaps inet_ad return (0) ,- else return (dpi ♦ 0x1000000) + (ip2 0x10000) + (ip3 0x100) + (ip4)),-} int str2port (char str) { int port=0; if (sscanf (str, "% [~\ [] [%d" , kport) )
Say ( "str2port %s returns %d" , str, port ) ; else
Say("str2port %s FAILED" , str) ,- return (port) ,- }
// Routing table entry, , , , to be deleted typedef struct rte ( // int ip; // char node [NAMESIZE] ,- // char ntype [NAMESIZE] ,- // char cs [NAMESIZE] ; // int qnetd port; // char serv class [NAMESIZE] ;// char servers [4*NAMESIZE] ; // char physical [NAMESIZE] ; // char logicals [4*NAMESIZE] ;// char serv path [NAMESIZE] ; // char serv opts [NAMESIZE] ; // 000204
} RTE, lpRTE;
static int ιs_ιp(char s) ( return ( lsdigit (s [0] ) ) ,- } static int ιs_stype (char *s ) ( return ( strlen (s) > 3 && strstr ( &CLASSNAMES , s) ), )
// The table looks like this:
//137.203.1.1 mars NT3.5 Server [100]
// classO router c:/q/route -master
// classl QS1 [Q1,Q2,Q3] c : /q/qserv -threads 66 -more opts
//
// The node line is.
// IP# node_name node type Clιent_or_server [QNETD address] Preferred servers,,,
//
// The Services lines is:
// type physιcal_name [logιcal_names, , , ] path_to_executable options t parseRTnode char line ,
Figure imgf000207_0001
char ntype , char cs , t port, char servers) char ιp_str [NAMESIZE] ; char cs_str [LINESIZE] , strcpy (servers, " , " ) ; if ( 4 > sscanf (l ne, "%s %s %s %s %s" , ιp_str, node, ntype, cs_str, -servers [1] ) ) Fail ("Routing Table Line %d is not complete: %s" , line no, line) ; if (strlen (servers) > 1) strcat ( servers ,","); else strcpy ( servers , " " ) ; if (If^ip = str2ιp(ιp_str) ) )
Fail ( "Routing Table Line %d ip does not scan- %s" , lme_no, line) ; if (2 != sscanf (cs_str, "%["\[] [%d] ",cs, port) )
Fail ("Routing Table L ne %d QNETD client/server does not scan: %s",lme_no return (1) ,- } t parseRTservices (char line, t line no, char class, char ♦physical_name, char ♦logical names, char ♦path, char *opts) { 000£05
char services [LINESIZE] ; int len; strcpy (opts , " " ) ,- if ( 3 > sscanf (line, "%s %s %s %["]", class, services , path, opts) )
Fail ( "Routing Table: line %d is not complete: %s" , line_no, line) strcpy ( logical_names , " , " ) ; sscanf (services, "% [ ~ \ [] [%s] " , physical_name, &logical_names [1] ) ; if ((len = strlen (logical_names) ) < 2) // No logical name sprintf (logical_names, " , %s, " , physical_name) ; else logical_names [--len] = ','; return (1) ; }
/* * *
♦♦char NewStr(char s) (
* char n = malloc (strlen (s) +1) ;
* if (In) FailC'Malloc error in NewStr");
* return (strcpy (n, s) ) ; ** I
♦♦void FreeNcopy (char ** o, char s) {
♦♦ char ♦ n = malloc (strlen (s) +1) ;
* if (In) FailC'Malloc error in FreeNcopy");
♦♦ strcpy (n, s) ,-
** free (o) ;
* ♦ ♦o = n ; ** \
* *
*/
void SwapRTdpRT RT1, IpRT RT2) { IpRT P,R,PRT1=0,PRT2=0;
Diag("SwapRT(%s,%s) " , RT_NODE (RT1 ) , RT_NODE (RT2) ) ; if (RT1 == RT2) return;
// Scan for the prel and pre2 nodes
P = RTROOT; while (R = NextRT(P)) ( // Find both the previous nodes if (R == RT1) PRT1 = P; if (R == RT2) PRT2 = P;
P = R;
} if (!(PRT1 && PRT2)) return;
// Swap pointers
PRTl->next_offset = RT2C(RT2) - RT2C(PRT1); if (RT2->next_offset) PRT2->next_offset = RT2C (RT_NEXT (RT2) ) - RT2C(PRT2) else PRT2->next_offset = 0 ;
RT2->next_offset = RT2C(RT1) - RT2C(RT2);
} int fgetshtchar ♦line, int max, HANDLE rth) { // Aproximate fgets ( ) int rd=l,rdn=0;
00020R
while ((rdn < max) && ReadFile (rth, line, 1, &rd, 0) ) { if (rd ι= 1) break; if (*lιne == '\n') break; hne+t, rdn++;
} if (line = '\n') line--; if (rd) lιne++;
line = 0; return (rdn) ,
} void ReadRTO { // Should only be called by QNETD. int lιne_no = 0, char line [LINESIZE] ; char first [LINESIZE] ; char preferred [LINESIZE] ,- //FILE ♦fp = fopen (ROUTNAME, "r") ; HANDLE rth = CreateFile ( ROUTNAME ,
GENERICJWRITE | GENERIC_READ ,
FILE_SHARE_W ITE | FILE_SHARE_READ , 0 ,
OPEN_ALWAYS ,
FILE_ATTRIBUTE_NORMAL, 0) ; RTE rte, // Current RTE IpRT rt.rts; char cp;
if (SHAREDATA (rtjpingpong) ) // Not the active RT rts = rt = (IpRT) smjbase - >RT [0] ; else rts = rt = (IpRT) sm_base->RT [1] ,
memset (rt, 0 , MAXRTSIZE) ; // Clear routing table (not required) cp = rt->s + 1; // 1st node is always nop rt->ntype_mdex = cp++ - (char ) rt->s; // 1st node is always nop rt->apps_mdex = cp++ - (char ) rt->s; // 1st node is always nop strcpy (preferred, " ") ; if ( I rth )
Fail ("Cant open the Routing Table s" , &ROUTNAME) ; while (fgetsh(line,LINESIZE-l,rth) ) ( lme_no++ ,- sscanf (line, "%s" , first) ; if (first == 'tt' ) { line no = lιne_no; } else if (ιs_ιp (first) ) { // New node //
// Perhaps we can filter other clinets out here to save space // parseRTnode (line, lme no, &rte . ip, rte .node, rte . ntype , rte . cs , fcrte . qnetd_port , rte . servers ) ,-
// Start a new node the RT RT_NOFFSET(rt) = ++cp - RT2C(rt); rt = NextRT(rt) ; // Build RT shared memory
RT IP(rt) = rte.ip; // IP number
RT_PORT(rt) = rte.qnetd_port; // Port number RT_NOFFSET(rt) = 0; // End of the chain strcpy (RT_N0DE(rt) , rte .node) ,- // Node string rt->ntype_mdex = strlen (RTJNODE (rt) ) + 1; strcpy (RT_NTYPE(rt) , rte. ntype) ,- rt->apps_ dex = strlen (RT_NTYPE (rt) ) + 1 + rt- >ntype_ιndex, cp = RT_APPS(rt) ; cp = 0;
if ( I strcmp (SHAREDATA (hostname) ,RT_NODE(rt) ) ) { strcpy (preferred, rte . servers) ,-
SHAREDATA (hostip) = RT_IP(rt);
Dιag( "ParseRT this node is %s ip=%p" , SHAREDATA (hostname) , SHAREDATA(h }
} else if (ιs_stype (first ) ) { // New service // parseRTservices (line, line no, rte . serv_class, rte .physical, rte . logicals, rte . serv_path, rte. serv_opts) ; // format: [QS1] , Ql , Q2 , [QS2] , Q4 , sprintf (cp, " [%s] %s" , rte .physical , rte . logicals) ; cp = strchr (cp, 0) ,- // Advance the pointer
} else if (! strcmp (first, "RTJVERSION" ) ) ( sscanf (line, " % *s %d" , &SHAREDATA(rt ver) ) ;
// if (ferror(rth) ) {
// Fail ( "ParseRT read error on %s . \n" , &ROUTNAME) ;
// clearer (rth) ;
// }
CloseHandle (rth) ,-
// Sort this list according to the preferred servers PnntRTfrts, "Before sorting") ,- if (strlen (preferred) > 2) ( IpRT rtf, rtp = NextRT (rts) ; char e.^p = preferred + 1 ,-
DiagC'ReadRT: Sorting preferred servers : %s" , preferred) ,- // Swap entries to achive the right order while (rtp && ((strlen(p) > 2))) ( if (e = strchr (p, ',') ) *e = 0; rtf = rts; while (rtf = NextRT (rtf)) if ( I strcmp (RT_NODE (rtf ), p) ) break; if (Irtf) {
SayO'ReadRT: Cant find preferred server %s",p); break;
}
SwapRT(rtp,rtf ) ; rtp = NextRT (rtp) ; if (e) p = e + 1; else break;
}
PrintRT (rts, "After sorting");
}
// Ping Pong the RT tables, make this one active if (SHAREDATA (rt_pingpong) )
SHAREDATA (rt_pingpong) = 0 ; else
SHAREDATA (rt_pingpong) = 1 ; SHAREDATA (rt_rev) ++; // Every handle will re-load from new RT .
// We must find some way to set the IP addr, and the RT is the only way to ge if ( I SHAREDATA (hostip) )
WarnC'ReadRT: could not find host %s in the file %s" , SHAREDATA (hostname) , &
/*
* *
♦♦ Copyrigh (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
♦♦ UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
♦♦ LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
* IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
♦♦ OR DISCLOSURE.
**
♦♦ THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
♦♦ TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
♦♦ OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
♦♦ EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
+ *
♦♦ OpenMQ
♦♦ Module: routab.c
♦♦ Author: Derek Schwenke 9/8/95
* *
♦♦ Routing table funtions */ ttinclude "qlib.h" ttinclude "rt.h" ttinclude "netadmin.h" ttinclude <string.h> ttinclude <ctype.h>
IpRT NextRT (IpRT rt){ if (rt- >next_offset ) retur (RT_NEXT(rt) return (0) ;
} void PrintRT pRT r,char s) (
Diag("\n\n\t\tRouting Table %s\n",s); while (r = NextRT (r) ) (
Diag("%8s %7s %p[%4d] %s" , RT_NODE (r) , RT_NTYPE (r) r->ip,r->qnetd_port,RT_APPS (r) ) ,- } Diag ( " " ) ,- }
IpRT ServerByNode (char node) { IpRT rt = RTROOT; while (rt = NextRT(rt)) { if ( I strcmp (RT_NODE(rt) , node) ) break; return (rt) ,- }
IpRT RTByName (char name) ( IpRT rt = RTROOT; while (rt = NextR (rt)) ( if ( I strcm (RT NODE (rt) , name) ) break; }
return (rt)
IpRT RTBylP ( t IP) { IpRT rt = RTROOT, while (rt = NextRT (rt)) { if (IP == rt->ιp) break, return (rt) ,
t Str2IP(char str) { t lpl, ιp2 , ιp3 , ιp4 , if ( 4 ' = sscanf (str, "%d %d id %d" , &ιpl, &ιp2, &ιp3, &ιp4) ) // Perhaps ιnet_ad return (0) , else return (dpi 0x1000000) (ιp2 * 0x10000) + (ιp3 0x100) + (ιp4) ) ,
int Name2IP (const char name) ( IpRT rt, if (rt = RTByName ( (char *) name)) return (RT_IP(rt) ) , else return (Str2IP ( (char ) name)),
char IP2NameStr [40] , char^ IP2IPstr(mt ip) ( unsigned long l = ip, sprintf (IP2NameStr, "%d %d %d %d", ( (ι/0x01000000L) & OxOOFFL) , ( (l/Ox00010000L) & OxOOFFL ( (l/OxOOOOOlOOL) & OxOOFFL (i & OxOOFFL )), return (IP2NameStr) , } char^ IP2Name(mt ip) ( IpRT rt = RTBylP p), if (rt) return (RT_NODE (rt) ) , else return (IP2IPstr p) )
char^ IP2NameOrNull (int ip) { IpRT rt = RTBylP p) , if (rt) return (RT_NODE (rt) ) , else return (0) ,
// Called by Qopen
IpRT RTByService (lpQHANDLE q) { char sname [LINESIZE] ,- char p;
IpRT rtp = RTROOT; sprintf (sname , " , %s, " , q->msgh. to_logical) ,- while (rtp) { if (p = strstr (RT_APPS (rtp) , sname) ) if ( I ServiceHasFailed(q->msgh. tojlogical, RT_IP (rtp) ) ) break; rtp = NextRT (rtp) ; } if (rtp) ( // Extract the physical server name while (*p != ' [' ) p--; sscanf (p, " [% [~\] ]", q- msgh. to_server) ; // physical server } else { // Try the local node if (SMByName (q->msgh. to_logical) ) ( rtp = RTBylP (SHAREDATA (hostip) ) ; // Return this node strcpy (q->msgh. to_server, q->msgh. to_logical) ; // physical = logical
return (rtp) ,- // Null == failed
// Called by Qopen
IpRT ServerByName2 (IpRT rtp, char name, int index, char physical) char sname [LINESIZE] ; char ♦p; sprintf (sname, " , %s , " , name) ; while (rtp) { if (p = strstr (RT_APPS (rtp) , sname) ) if (I (index--)) break; // Find the Nth entry rtp = NextRT (rtp) ;
if (rtp && physical) ( // Extract the physical server name while (*p != ' [' ) p--,- sscanf (p, " [% [~\] ] ", physical) ,-
return (rtp) ; // Null == failed
}
IpRT GetRTroot () ( // Used by GUI apps that want to find the RT if (!sm_base) AttachSharedMemory () ; return (RTROOT) ,- }
ttdefine TROUTNAME "c : \\q\\routing. tmp" int BroadcastRT ( ) (
FILE+ rtf = fopen (ROUTNAME, "r") ;
IpRT rt = RTROOT;
lpQHANDLE qh = Qopen ( "QNETD" , PUTJMODE, 0 , 0 , 0 , 0 , 0 ) ; SMBUF b ; int sz ,-
DiagC'BroadCastRT") , if (Iqh | | Irtf) return (0); memset (&b, 0 , sizeof (b) ) , qh->tιme_out = 1000, // One second strcpy (qh->msgh. to_logιcal, "QNETD") ; strcpy (qh->msgh. to_server, "QNETD") , sz = fread (&b. data, sizeof ( char ), MAXMSGDATA, rtf ) , fclose ( rtf ) , while (rt = NextRT(rt)) ( SayC'BroadCastRT Trying %d" , RT_IP (rt ) ) ; if (RTJIP(rt) == SHAREDATA (hostip) ) continue, // skip this n if (strstr (RT_NTYPE (rt) , "NOBROADCAST") ) continue, // skip this node qh->rrsgh. to_node = RT_IP(rt) ; qh->msgh.to_port = RT_PORT(rt),
Qput (qh,QNETDREQ_MODE,NETMAN_RT_NEW, 0,sz,b mdata) ,
return (1)
CopyRT nt ip) (
IpRT rt , lpQHANDLE qh = Qopen ( "QNETD" , PUTJMODE, 0 , 0 , 0 , 0 , 0 ) , SMBUF b, if ( Iqh) return (0) ,
// qh->tιme_out = 1000; // One second strcpy (qh->msgh.to_logιcal, "QNETD") ,- strcpy (qh->msgh.to_server, "QNETD") ; if (rt = RTBylP dp) ) { SayC'CpyRT Trying %d" , ip) ; qh->msgh.to_node = RT_IP(rt); qh->msgh.to_port = RT_PORT(rt);
QsendAndReceive (qh, QNETDREQ_MODE , ETMAN_RT_GET, 0,0,0, MAXMSGDATA, b. mdata, 0,&b. sgh) ; // Write to file if (b. msgh. size > 10) {
FILE fp = fopen (ROUTNAME, "w") ;
SayC'CpyRT saving copied table %d bytes %s",b msgh. size , b .mdata) fwrite (b. mdata, sizeof ( char ), b. msgh. size, fp) ; fclose (fp) ,
// ReadRTO , called by watchdog. c when file time changes
}
} else return (0) ,- return (1) ,-
/* **
* * Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED. ** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE ** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION ** OR DISCLOSURE. ** ** THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
** TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
** ** OpenMQ ** Module: rt.h ** Author: Derek Schwenke.10/8/95
* * ** Routing table header
*/
// Routing table structure
/* typedef struct rt ( // Routing Table in shard memory int ip; // int qnetd_port; // int next_offset; // int ntype_index; // int apps_index; // char s [0] ,- // node\0ntype\0apps\0 <<More than 4 char>>
} RT, IpRT;
*/ ttdefine RT2C(rt) (char ♦) (rt) ttdefine RT_NODE(rt) rt->s ttdefine RT_IP(rt) rt->ip ttdefine RT_PORT(rt) rt - >qnetd_port ttdefine RTJJOFFSET(rt) rt->next_offset ttdefine RT_APINDEX (rt) rt- >apps_index ttdefine RT_NTINDEX (rt) rt- >ntype_index ttdefine RT_NEXT(rt) (IpRT) (RT2C(rt) + rt->next_offset) ttdefine RT_APPS(rt) & (rt->s [rt->apps_index] ) ttdefine RT_NTYPE(rt) &(rt->s [rt->ntype_index] )
// From routtab.c ttifdef CPP extern "C" ttendif int MarkFailedServer (lpQHANDLE q) ; void UpdateHandle (lpQHANDLE q) ; lpFOL ServiceHasFailed(char name, int ip) ,-
IpRT RTByService (lpQHANDLE q) ;
IpSMBUF SMByName(char ♦name); // move to qlib.h? charA IP2Name (int ip) ; int Name2IP (const char name); void ReadRT ;
IpRT NextRT (IpRT rt) ,- void PrintRTdpRT r,char s) ,-
IpRT ServerByNode(char node); 000214 //IpRT IPByName ( char name) ;
IpRT RTByName ( char name ) ;
IpRT RTBylP ( int IP) ;
IpRT ServerByName2 (IpRT rtp, char name, int index, char ♦physical)
IpRT GetRTroot () ,- // Used by GUI apps that want to find the RT
// routtab.c - int BroadcastRT ; // used by netman int Copy RT ( int ip) ; // used by netman
ttifdef .CPP
} ttendif
/* **
** Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
** OR DISCLOSURE.
**
** THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
* + TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE, ** OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* * EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
* *
** OpenMQ
* * Module : shm_acc . c ** Author: Derek Schwenke 9/8/95 ** **
*/ ttinclude "qlib.h" ttdefine TABLETIMEOUT 10000 void ForcedBufferReset (int bnum, // Optional Buffer number (-1 = not us lpQHANDLE q, // Optional Queue Handle (if set also int objn) { // Optional object number in Queue Han // This routine called only as repair after some failure.
SMOBJS sync ;
IpSMBUF buf = SMBUFADDR (bnum) ; int found, rtn, opened=0 ,- char name [NAMESIZE] ; if ( (q) && (obj n < 64 ) ) ( sync . freeh = q- >f reeh [obj n] ,- sync . readyh = q- >readyh [objn] ,- sync . doneh = q- >doneh [obj n] ; sync . ackh = 0 ,- bnum = q->bufs_found [objn] ; buf = SMBUFADDR (bnum) ; } else if ( (bnum >= 0) && (bnum < SHAREDATA (nsbuf) ) ) ( opened++ ; sprintf (name,MUTFREFMT, found) ; if (! (sync.freeh = OpenMutex (SYNCHRONIZE, FALSE, name)))
Warn ("ForcedBufferReset [%d=%s] : OpenMutex %s failed #%d" , bnum, buf->name sprintf (name, SEMRDYFMT, found) ; if ( I (sync. readyh = OpenSemaphore (SYNCHRONIZE, FALSE, name)))
Warn ( "ForcedBufferReset [%d=%s] : OpenSemaphore %s failed #%d" , bnum, buf- sprintf (name, SEMDONFMT, found) ; if ( I (sync. doneh = OpenSemaphore (SEMAPHORE_ALL_ACCESS , FALSE, name)))
Warn ("ForcedBufferReset [%d=%s] : OpenSemaphore %s failed #%d" , bnum, buf-> sprintf (name, SEMACKFMT, found) ; if ( I (sync. ackh = OpenSemaphore (SEMAPHORE_ALL_ACCESS, FALSE, name)))
Warn ( "ForcedBufferReset [%d=%s] : OpenSemaphore %s failed #%d" , bnum, but- > } else ( sync. ackh = sync. doneh = sync. readyh = sync.freeh = NULL;
Warn ( "ForcedBufferReset Fails: bad args bnum=%d q=%p objn=%d" , bnum, q, objn)
// These Semephores have two states .
// To reset first release then reaquire them
/ * if ( I ReleaseSemaphore (sync . readyh, 1,NULL) )
Warn (" ForcedBufferReset [%d=%s] : ReleaseSemaphore ready readyh #%d",bnum if ( I ReleaseSemaphore (sync .doneh, 1,NULL) )
Warn ( "ForcedBufferReset [%d=%s] : ReleaseSemaphore ready doneh #%d'l,bnum, if ( I ReleaseSemaphore (sync . ackh, 1,NULL) )
Warn ( "ForcedBufferReset [%d=%s] : ReleaseSemaphore ready ackh #%d",bnum b */ if (sync . readyh) if ( (rtn = WaitForSingleObject (sync .readyh, 10) ) != WAIT TIMEOUT )
Warn ( "ForcedBufferReset [%d=%s] : WaitForSingleObject readyh was reset", b if (sync. doneh) if ( (rtn = WaitForSingleObject (sync. doneh, 10) ) != WAITJTIMEOUT )
Warn ( "ForcedBufferReset [%d=%s] : WaitForSingleObject doneh was reset", b if (sync. ackh) if ( (rtn = WaitForSingleObject (sync .ackh, 10) ) != WAITJTIMEOUT )
Warn ( "ForcedBufferReset [%d=%s] : WaitForSingleObject ackh was reset", bnu if (sync.freeh) if ( I ReleaseMutex (sync . freeh) )
Warn ( "ForcedBufferReset (%d=%s) : ReleaseMutex freeh fail GetLastError = bnum, buf->name, GetLastError 0 ) ; if (opened) {
CloseHandle ( sync . freeh) ,- CloseHandle (sync .readyh) ,- CloseHandle (sync .doneh) ,- CloseHandle (sync . ackh) ;
IpSMBUF SMByName (char ♦name) { int i ,- for (i = 0; i < SHAREDATA (nsbuf) ; i++) if ( I strcmp (name, (SMBUFADDR (i))- >name) ) return (SMBUFADDR (i) ) ; return (0) ; }
// This routine is called at startup by QNETD and QSERV. // It's not done often so efficency is no issue here.
// This routine allocates 1 buffer and returns the buffer number or -1 on error. // seqno specifes the number of existing buffers to expect already allocated. int ReserveSharedBuffer (int seqno, char bname, int bstatus,
IpSMOBJS sync) { int used, found, i, rtn; char name [NAMESIZE] ; IpSMBUF BUF; HANDLE SMT = OpenMutex ( SYNCHRONIZE, FALSE, SMEMTABLE ) ; Diag ( "ReserveSharedBuffer (%s) starts...", bname) , if (I SMT) // SMT control all changes to the shared memory buffers
Fail ("ReserveSharedBuffer (%s) : Cant OpenMutex for the table %d", bname, Ge if ((rtn = WaitForSingleObject (SMT, ABLETIMEOUT) ) != WAIT_OBJECT_0 ) Faιl(" Failed while waiting for the table %d",rtn);
// Count the existing number of buffers registered under this name used = 0; // number of times we saw the name found = -1; // first empty buffer found for (ι = 0, l < SHAREDATA (nsbuf) ; ι++) { BUF = SMBUFADDR (l) ;
Diag ( "Checking buf %s" , BUF->name) , if ( I strcmp (BUF->name, bname) ) { if (used >= seqno) (
Say ( "ReserveSharedBuffer (%s) FOUND STALE EXISTING BUFFER [%d] " strcpy (BUF- >name, "empty") , BUF->status = SMBUF_EMPTY, } else ( Diag ( "ReserveSharedBuffer (%s) . found an existing buffer[%d] " , bna used++ ,
' ) if ((found == -1) && ( I strcmp (BUF- >name, "empty") ) ) found = I,
if (found == -1) {
Warn ( "ReserveSharedBuffer (%s) :Cant allocate a buffer - all %d currently i return (found) , }
// Get handles for free ready and done objects
// All have previously been created by sharmemmit
BUF = SMBUFADDR (found) ; sprintf (name,MUTFREFMT, found) , if ( I (sync->freeh = OpenMute (SYNCHRONIZE, FALSE, name)))
Fail ( "ReserveSharedBuffer (%s) : OpenMutex %s failed #%d" , bname, name, GetLast if (sync->freeh) ReleaseMutex (sync- >freeh) ,- // I dont own this mutex, This ca GetLastError () ; // clear this error out sprintf (name, SEMRDYFMT, found) ; if ( ! (sync->readyh = OpenSemaphore (SYNCHRONIZE, FALSE, name)))
Fail ("ReserveSharedBuffer (%s) : OpenSemaphore %s failed tt%d", bname, name, Ge if (sync->readyh) WaitForSingleObject (sync->readyh, 10) ,- // Reset sprintf (name, SEMDONFMT, found) ; if ( I (sync->doneh = OpenSemaphore (SEMAPHORE_ALL_ACCESS, FALSE, name)))
Fail ( "ReserveSharedBuffer (%s) : OpenSemaphore %s failed tt d", bname, name, Get if (sync->doneh) WaitForSingleObject (sync->doneh, 10) , // Reset sprintf (name, SEMACKFMT, found) ; if ( I (sync->ackh = OpenSemaphore (SEMAPHORE_ALL_ACCESS, FALSE, name)))
Fail ("ReserveSharedBuffer (%s) : OpenSemaphore %s failed tt%d" , bname, name, G»t if (sync->ackh) WaitForSingleObject (sync->ackh, 10) ,- // Reset
// Set name and status strcpy (BUF->name, bname) ,- BUF->status = bstatus;
ReleaseMutex (SMT) ;
Diag ( "ReserveSharedBuffer (%s) returns [%d] addr %p" , bname, found, BUF) return (found) ;
int UnReserveSharedBuffer (int bnum) { int rtn = 0,- IpSMBUF BUF = SMBUFADDR (bnum) ; HANDLE SMT = OpenMutex ( SYNCHRONIZE, FALSE, SMEMTABLE ) ;
Diag ( "UnReserveSharedBuffer(%s) ", BUF->name) ,- if (I SMT)
Fail ( "UnReserveSharedBuffer (%s) : Cant OpenMutex for the table %d", BUF->na if ((rtn = WaitForSingleObject (SMT, TABLETIMEOUT) )" != WAIT_OBJECT_0 ) FailC Failed while waiting for the table %d",rtn); ~ strcpv (BUF->name, "empty") ; BUF->statUΞ = SMBUF_EMPTY; ReleaseMute (SMT) ;
return (rtn) ;
// This routine is called at startup by QNETD and QSERV. // It's not done often so efficency is no issue here. IpSMBUFH AttachSharedMemory () {
HANDLE hMap; // Shared memory mapping
//Say ("AttachSharedMemory \n") ,-
// Open the shared memory object if ( I (hMap = OpenFileMapping (FILE_MAP_WRITE, FALSE, SMEMNAME) ) ) Warn ( "OpenFileMapping returned null - QNETD is not running"),-
// Map the shared memory into my address space else { if (I (smjbase = (IpSMBUFH) MapViewOfFile ( hMap, FILE_MAP_WRITE, 0 , 0 , 0) ) ) Warn ( "MapViewOfFile returned null");
// Note: hMap is not returned because we dont expect anyone // to ever close this mapping once they have it.
Diag ( "AttachSharedMemory %s returns %p" , &SMEMNAME, smjbase) ; return (sm base) ,- /* **
♦♦ Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
♦♦ LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
♦♦ IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
♦♦ OR DISCLOSURE.
**
♦♦ THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
♦♦ TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
♦♦ OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
♦ EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
♦♦ OpenMQ
♦♦ Module: tran.c
♦♦ Author: Derek Schwenke 9/8/95
**
♦♦ Tran routines for single threaded clients, or well behaved
♦ multi threaded clients. There will be problems if 2
♦ threads do different COMMITS So, this code is not thread safe.
*/ ttinclude "qlib.h"
//typedef struct tl { // Message header
// struct tl *next; // Next
// QHANDLE q; // Header version, and machine coding format
//} TL, ♦lpTL; lpQHANDLE TLroot = NULL // Open transaction list int tran_id = 1; // Transactional ID for this process int last_tran_id; // Last commited ID lpQHANDLE FindTL (lpQHANDLE q) ( lpQHANDLE tl = TLroot; while (tl) if (strcmp (tl->msgh. to_logical, q->msgh. to_logical) == 0 && strcmp (tl->msgh. to_server, q->msgh. to_server) == 0) break; else tl = tl->next; return (tl) ,-
void TLadd ( lpQHANDLE q) { lpQHANDLE n; if ( n = FindTL (q) ) ( n->msgh.sub_mode++; // Inc # of times used } else { n = (lpQHANDLE) malloc (sizeof (QHANDLE) ) ;
DiagC'TLadd: Starting for %s %s" , q->msgh. to_logical, q->msgh. to_server) ,- memcpy (n, q, sizeof (QHANDLE) ) ; n->msgh.sub_mode = 1; // # of times used n->msgh.mid. tid = tran_id; // Save for acks n->next = TLroot; TLroot = n;
void TLdel ( lpQHANDLE nn,n = TLroot; while (nn = n) ( n = n->next; free (nn) ,- } TLroot = NULL;
char open_tran [1000] ,- char old_trans [1000] ,- FILE ♦TLOG = NULL; // Message Log File void LogTran(char ♦s) ( if (I TLOG) if (I (TLOG = fopen (TLOGNAME, "w") ) )
Fail ("ERROR CAN NOT OPEN LOG FILE %s " , &TLOGNAME) fprintf (TLOG, "%s",s) ;
void Qcommit (int action) { // Commit or abort // 1. Mark it commited on DISK // 2. Add to RAM list // 3. Send commit messages char transtr [80] ,- int trouble = 0; lpQHANDLE tl = TLroot; MSGH mh;
Diag ( "Qcommit (%d) ", action) ,-
// The Open Transaction List should have accumulated q's to commit if (Itl) {
Diag ( "Attempt to commit with no outstanding messages Ignored" ),- } else { strcpy (old_trans,open_tran) ,- sprintf (transtr, " :%d=%d" , TLroot ->msgh. mid. tid, action) ; strcat (open_tran, transtr) ;
LogTran (open_tran) ; // <-- This is the real commit
Diag ( "Qcommit (%d) transtr=%s open_tran=%s" , action, transtr, open_tran) ;
// Try to notify everyone about the commit or abort while (tl) { mh.mode = 0; // Clear incase no full header is recived. QsendAndReceive (tl, action, 0, 0, 0,0, 0,0,0,&mh); if (mh.mode == ACK_MODE)
Diag ("Qcommit: was acknoledged I " ) ; else
Diag ("Qcommit: WAS NOT ACKNOLEDGED" , trouble++) ; tl = tl->next;
TLdel O ; // Clean up if ( I trouble ) ( // Remove from the open tran list strcpy ( open_tran, old_trans ) ,- if dopen tran) LogTran (open tran) ;
} if (♦open_tran) Say ( "Qcommit : open_tran= [%s] " , open_tran) ; last tran id = tran id;
int ResolveTran pMID MID) ( int i, state = Q_ABORT; char *p , id [40] ,- sprintf (id, " :%d, ",MID->tid) ; if (p = strstr (old_trans, id) ) // If this mid is on the old scanf (p, ": %d=%d" , i, state) ; // Read the tran state else if ( TLroot ) // If there's a inflight transaction if (TLroot ->msgh. mid. tid == MID->tid) // And the msg# matches state = Q_INPROGRESS ; // Return "inprogress" if (SHAREDATA (hostip) != MID->host) {
Warn ("ResolveTran PASSED the wrong host"); state = Q WRONGHOST;
} return (state) ;
}
// This code is executed in each client's address space. // But it should return a unique number void SetTIDdpMID m, int flags) { if (flags & QJTRAN) ( // It's transactional make a ID if (BITSET(Q_TRAN_BEGIN, flags) I I (tran_id == last_tran_id) ) tran_id = ++ (SHAREDATA (tran_id) ) ; // Generate new tran ID for this NODE DiagC'SetTID id=%d" , tran_id) ; m->tid = tran id;
}
// Always make a unique id for each message. m->uid = ++ (SHAREDATA (unique_id) ) ; /*
* *
** Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED. ** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE ** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION ** OR DISCLOSURE. ** ** THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND ** TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
* * OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR ** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA. ** ** OpenMQ ** Module : copyrt . c ** Author : Derek Schwenke 11 /20 / 95 ** ** Routing table broadcas t funt ions
*/ tt include " ql ib . h " tt inc lude " qnetd . h " tt include " rt . h " ttdef ine TROUTNAME "c : \\q\\routing. tmp' void BroadCastRT ( ) ( FILE* rtf = fopen (ROUTNAME, "r" ) ; FILE * trt = fopen (TROUTNAME, "w") ; IpRT rt = RTROOT; lpQHANDLE qh Qope ( "QNETD" , PUT_MODE ,0,0,0,0,0) ; SMBUF b; int rd;
Say ("BroadCastRT") ,- if (Iqh || I rtf ) return; memset (&b, 0, sizeof (b) ) ; qh->time_out = 1000; // One second strcpy (qh->msgh.to_logical, "QNETD") ; strcpy (qh->msgh. to_server, "QNETD") ; rd = fread (&b. mdata, sizeof ( char ), MAXMSGDATA, rtf ) ,-
Say ("BroadCastRT read got %d bytes " , rd) ,- fclose ( rtf ) ,-
Say ("BroadCastRT closed" , b. mdata) ,- rd = fwrite (&b.mdata, sizeof ( char ) MAXMSGDATA, rtf) ;
Say ("BroadCastRT wrote %d " , rd) ;
/ while (rt = RT_NEXT(rt)) ( qh~>msgh.to_node = RT__IP(rt); qh->msgh.to_port = RT__PORT (rt) ,-
QsendAndReceive (g_q, QNETDREQJMODE, NETMAN_SMBUFH, 0,0,0,
(sizeof (SMBUFH) - MAXRTSIZE) , (char ) &g_smhead, 0 , 0) ;
7 int CopyRT dnt IP) {
IpRT rt = RTROOT; lpQHANDLE qh = Qopen ( "QNETD" , PUT_MODE ,0,0,0,0,0) ; if ( Iqh) return(O) ,- qh->time_out = 1000; // One second strcpy (qh->msgh.to_logical, "QNETD") ; strcpy (qh->msgh. to_server, "QNETD") ;
/* while (rt = RT_NEXT(rt)) { qh->msgh.to_node = RTjIP(rt); qh->msgh.to_port = RT_PORT (rt) ;
QsendAndReceive (g_q, QNETDREQJMODE, NETMAN_SMBUFH , 0,0,0,
(sizeof (SMBUFH) - MAXRTSIZE) , (char ♦) &g_smhead, 0 , 0)
* / return ( 1 ) ;
}
/* **
♦* Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
♦♦ UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
♦♦ LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
♦♦ IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
♦♦ OR DISCLOSURE.
**
♦♦ THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
♦♦ TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
♦♦ OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
*♦ EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
♦♦ OpenMQ
♦♦ Module: failover. c
♦♦ Author: Derek Schwenke 9/22/95
*/ ttinclude "qlib.h"
// Make entry in the fail over list int MarkFailedServer (lpQHANDLE q) { lpFOL fl = &(smJbase->FO[SHAREDATA(failed_servers) ] ) if (SHAREDATA (failed_servers) < MAXFOLENT - 1) ( strcpy ( f1- >name , q->msgh. to_logical) ; fl->ip = q->msgh. to_node; SHAREDATA (failed_servers) ++; SHAREDATA (rt_rev) ++ ; return (1) ;
} return (0) ;
}
// Returns lpFOL if this server has failed lpFOL ServiceHasFailed (char ♦name, int ip) ( int i ; for (i=0;i<SHAREDATA(failed_servers) ;i++) { lpFOL fl = &( smjbase- >FO [i] ) ; if ( I strcmp (name, fl->name) && fl->ip == ip) return (f1) ;
} return (0) ;
void UpdateHandle (lpQHANDLE q) ( q->rt_rev = SHAREDATA (rt_rev) ; if ( (Q_FAILOVER & q->msgh . flags) && q->msgh.mode == PUTJMODE) { Qreθpen(q) ;
} }
/* int markfailed ( lpQHANDLE q, int pass) { lpQHANDLE failover; int rtn; // Note that this server has failed us, Find a new one
Warn ( "markf ailed ( %s) server on %p in pass=%d looking for replacement " , q- >msgh failover = Qopen ( q- >msgh . to_logιcal , q- >msgh . mode , q- >msgh . sub_mode , q- >base_flags ,
0 , 0,pass) ,-
// Add to failed list if (failover) ( failover- >next = FLroot;
FLroot = failover; rtn = 1; // good } else (
Say ("markfailed (%s) no replacement found pass=%d" , q->msgh. to_logιcal,pass) free (failover) ,- rtn = 0; // bad
} return (rtn) ;
lpQHANDLE fmdreplacment (lpQHANDLE q) ( lpQHANDLE fop = FLroot; // List of all failed servers while (fop) ( // Find first failover that matches if ( I strcmp (fop- >msgh. to_logιcal, q->msgh. to_logιcal) ) break; fop = fop->next, if (fop) (
Say ( "fmdreplacment (%s) Found a fail over" , q- >msgh. to_logιcal ) q = fop, // We found a fail over for this service
} return (q) ;
} void flushfailedlist ( ) { lpQHANDLE pp, cp = FLroot; // List of all failed servers if (Icp) return; FLroot = NULL;
//Sleep (60000) ; // Let any current transactions end while (pp=cp) cp = cp- >next ; free (pp) ; User: root Host : bunny Class : bunny Job: stdin
// QNETDREQ_MODE sub modes: ttdefine NETMAN_SMBUFH 100 ttdefine NETMAN_SMBUFS 101 ttdefine NETMAN_SOCKETS 102 ttdefine NETMANJTRAN 103 ttdefine NETMAN_RT_READ 104 // ttdefine NETMAN_RT_BROAD 105 ttdefine NETMAN_RT_NEW 106 ttdefine NETMANJRTJGET 107 ttdefine NETMAN CLR FOL 110
// Shared Buffers Status // typedef struct bs { // Shared memory buffers char name [NAMESIZE] ; short status; short sub_status; MSGH msgh ; BS, lpBS; typedef struct bsa ( // Shared memory buffers int nsbu ;
BS bs [MAXNSMBUF] } BSA, lpBSA;
// Socket Status
/ / typedef struct ss ( int ip; int port ;
} SS, IpSS ,- typedef struct ssa ( // Shared memory buffers int sockets; SS ss [FD SETSIZE] ;
} SSA, IpSSA;
// RT // — typedef struct rta ( // Shared memory buffers char RT [MAXRTSIZE] ; } RTA, lpRTA; // admindlg.cpp : implementation file //
ttinclude "stdafx.h" ttinclude "qman.h" ttinclude "admindlg.h" ttdefine Q_LIB ttinclude "qlib.h" ttinclude "qadmin.h" ttinclude "rt.h" ttdefine ADMTIMER 102 extern IpSMBUFH sm_base; extern QADMSTATS g_s[3]; extern CString g_que[3],- extern lpQHANDLE QS[3]; int IDC_APICS [8] = ( IDCJQNONE1 , IDC_QD0WN1 , IDCJQSTOP1 , IDC_QN0PUT1 , IDC_QNOGETl , ID enum pics (QNONE, QDOWN, QSTOP, QNOPUT, QNOGET,QUP, QNOPG, QFULL} ; extern int g_pic [3+3+3] ;
QADMCTLS g_ad; ttifdef _DEBUG ttundef THIS_FILE static char BASED_CODE THIS_FILE [ ] = FILE ; ttendif
extern CFont g_text font; int ALL_TEXT_A[] = JlDC_STATS , IDCJDGROUP, IDC_SGROUP,
IDC_PUTC, IDC_GETC, IDCJHALTC, IDC_SRESETC, IDC_FRESETC, IDC_SHU
IDC_MAXSIZE, IDC_LIMLAB, IDC QSIZE,
IDOK, IDC_SET, IDC_REFRESH, Oj;
///////////////////////////////////////////////////////////////////////////// // CAdminDlg dialog
CAdminDlg: : CAdminDlg (CWnd^ pParent /=NULL^/) : CDialog (CAdminDlg :: IDD, pParent)
//{ (AFX_DATA_INIT (CAdminDlg)
// NOTE: the ClassWizard will add member initialization here //} }AFXJDATA_INIT
void CAdminDlg: :DoDataExchange (CDataExchange^ pDX)
{
CDialog: :DoDataExchange (pDX) ;
// { (AFX_DATA_MAP (CAdminDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//} }AFX DATA MAP } ~ ~
BEGIN_MESSAGE_MAP (CAdminDlg, CDialog)
// { {AFX_MSG_MAP (CAdminDlg) Q ize)
Figure imgf000232_0001
///////////////////////////////////////////////////////////////////////////// // CAdminDlg message handlers void CAdminDlg: :SetDisplay (int init) { CString sp, sg, s, tl, t2 ; if (init) { tl = g_que [m_id] + " Status"; t2 = g_que [m_id] + " Settings";
SetDlgltemText (IDCJOGROUP, tl) ; SetDlgltemText (IDC_SGROUP,t2) ;
CListBox* lb = (CListBox^) GetDlgItem(IDC_STATS) ,- lb->ResetContent () ,- s . Format ( %5d committed entries" , g_s [m_id] . committed_entries) ; lb- >InsertStri s . Format ( %5d uncommitted puts", g_s [m_id] . pending_puts) ,- lb->InsertStri s . Format ( %5d uncommitted gets", g_s [m_id] .pending_gets) ,- lb->lnsertstri s . Format ( %5d holes", g_s [m_id] .holey_entries) ,- lb->InsertS' \ s . Format ( %5d max entries", g_s [m_id] . max_entries) ,- lb->InsertS sg = ctime (&g_s [m_id] . first_start_time) ,- sp = ctime (&g_s [m_id] . last_restart_time) ; s .Format ( "%5d restarts" , g_s [m_id] .num_restarts) ,- lb- >Insertstring ( -1 , s. Format ( "Last restart time %s" , LPCTSTR (sg. Left (24) )) ,- lb- InsertString ( -1 , s. Format ("First restart time %s" , LPCTSTR (sp.Left (24) ) ) lb- >Insertstring ( - 1 ,
if (init) { s. FormatC (%d limit) ",g_s[m_id] .max_entries_limit) ; SetDlgltemText (IDC_LIMLAB, LPCTSTR (s) ) ; SetDlgltemlnt (IDC_QSIZE,g_s [m_id] .max_entries) ,-
// Select a icon // if (init)
// for ( int i=0 ; i<6 ; i++)
// if ( i ! = g__pic [m_id] )
// GetDlgItem ( IDC_APICS [ i] ) >ShowWindow(SW HIDE)
if ( (g_pic [m_id] != g_pic [m_id+3+3] ) ) (
GetDlgItem(IDC_APICS [g_pic [m_id] ] ) ->ShowWindow (SW_SHOW) ; GetDlgItem(IDC_APICS[g_pic[m_id+3+3] ] ) ->ShowWindow (SW_HIDE) g_pic [m_id+3+3] = g_pic [m_id] ;
}
// Set check box items 000230 if (init) { ( (CButton ♦) GetDlgltem(IDCjGETC) ) ->SetCheck (g_s [m_id] . qget_state) ; ( (CButton ♦) GetDlgItem(IDC_PUTC) ) ->SetCheck (g_s [m_id] .qput_state) ; ( (CButton ♦) GetDlgItem(IDC_SRESETC) ) ->SetCheck (g_ad. stats_reset_flag) ( (GButton ♦ ) GetDlgltem(IDCJFRESETC) ) ->SetCheck (g_ad. full_reset_flag) ; ( (CButton ♦) GetDlgItem(IDC_HALTC) ) ->SetCheck (g_ad . halt_flag) ,-
BOOL CAdminDlg: :OnInitDialog()
CDialog: :OnInitDialog ( ) ,- g_pic [m_id+3+3] = QNONE; // history is invalid for (int i=0; i<6 ,- i++) // Turn all pics off.
GetDlgItem(IDC_APICS [i] ) - >ShowWindow (SWJHIDE) ,- SetDisplay (1) ;
SetTimer (ADMTIMER, 1000, NULL) ,- // 1 sec
i = 0; while (ALL_TEXT_A[i] )
GetDlgItem(ALLJTEXT_A[i++] ) - >SetFont (&g_text_font ) ;
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
void CAdminDlg: :OnRefresh ()
{
SetDisplay (1) ;
DWORD SetCtl (LPVOID m id)
{ int id = (int)m_id;
QsendAndReceive (QS [id] , ADMINREQ_MODE , QADM_SET_CONTROLS , 0 , sizeof (g_ad) , (char
g_ad. stats_reset_flag = 0 ,- g_ad. full_reset_flag = 0 ,- g_ad. shutdown_flag = 0; g_ad.halt_flag = 0; return (0) ;
void CAdminDlg: :OnSet 0 000231 memset (&g__ad, 0, sizeof (g_ad) ) ; if (IsDlgButtonChecked(IDCJPUTC) ) g_ad. enable_qputs_flag++ ; if (IsDlgButtonChecked(IDC_GETC) ) g_ad. enable_qgets_flag++ ; if (IsDlgButtonChecked(IDC_SRESETC) ) g_ad. stats__reset_flag++ ; if (IsDlgButtonChecked(IDC_FRESETC) ) g_ad . full_reset_flag++ ; if (IsDlgButtonChecked(IDC_SHUTDOWNC) ) g_ad. shutdown_flag++ ; if (IsDlgButtonChecked(IDC_HALTC) ) g_ad.halt_flag++ ; int qs = GetDlgltemlnt (IDCJ2SIZE, NULL, TRUE) ; if ( (qs>0) &&(qs<=g_s [m_id] . max_entries_limit ) ) g_ad.max_entries_value = qs;
DWORD id;
CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) SetCtl, (LPVOID) m_id, 0 , &id) ,- // QsendAndReceive (QS [m_id] ,ADMINREQ_MODE,QADM_SET_CONTROLS, 0 , sizeof (g_ad) , ( if (g_ad. shutdown_flag)'~{ g_pic[m_id] = QSTOP; // QSTOP=Yellow (QDOWN=RED) we will hit a comm error // SetDisplay (0) ,- // 0=refresh only. • ■
}
//Sleep(lOOO) ;
//SetDisplay (0) ,- // 0=refresh only.
//Sleep(lOOO) ,-
//if (g_ad.shutdown_flag) CDialog: :OnOK () ,- // Exit CDialog: :OnOK() ; // Exit
//g_ad. stats_reset_flag = 0 ,- //g_ad. full_reset_flag = 0; //g_ad.shutdown_flag = 0; //g_ad.halt_flag = 0;
//
//SetDisplay (1) ; // l=init: set buttons
} void CAdminDlg: :OnEditchangeQsize ( )
{ int qs = GetDlgltemlnt ( IDC_QSIZE , NULL, TRUE) ; if ( I ( (qs>0 ) && (qs<=g_s [m_id] . max_entries_limit ) ) )
SetDlgltemText (IDC QSIZE, "") ;
} void CAdminDlg: :OnTimer (UINT nIDEvent)
{ if (nIDEvent == ADMTIMER)
SetDisplay (0) ,- else CDialog: :OnTimer (nIDEvent ) ,-
} void CAdminDlg: :OnRButtonDown (UINT nFlags, CPoint point)
{
GetParentFrame () ->SetMessageText ("") ,- this->Invalidate () ,- CDialog: :OnRButtonDown (nFlags , point) ;
// admindlg.h : header file //
///////////////////////////////////////////////////////////////////////////// // CAdminDlg dialog class CAdminDlg : public CDialog
(
// Construction public :
CAdminDlg (CWnd^ pParent = NULL); // standard constructor
// Dialog Data
//( (AFX_DATA (CAdminDlg) enum { IDD = IDD_ADMINDIALOG } ;
// NOTE: the ClassWizard will add data members here //}}AFX_DATA int m_id;
// Overrides
// ClassWizard generated virtual function overrides // { (AFXJVIRTUAL (CAdminDlg) protected : virtual void DoDataExchange (CDataExchange^ pDX) ,- // DDX/DDV support //} }AFXJVIRTUAL void SetDisplay (int i) ;
// Implementation protected :
// Generated message map functions // ( (AFX_MSG (CAdminDlg) virtual BOOL OnlnitDialog ( ) ; afx_msg void OnRefresh ; afx_msg void OnSet ; afx_msg void OnEditchangeQsize ( ) ; afx_msg void OnTimer(UINT nIDEvent); afx msg void OnRButtonDown (UINT nFlags, CPoint point); //}τAFX_MSG DECLARE MESSAGE MAP ( ) }; - -
User: root Host : bunny Class : bunny Job: stdin
// datadlg.cpp -. implementation file // ttinclude "stdafx.h" ttinclude "qman.h" ttinclude "datadlg.h" ttinclude "KeySearch.h" ttdefine Q_LIB ttinclude "qlib.h" ttinclude "qadmin.h" ttinclude "rt.h" ttinclude "orderfm.h" extern lpQHANDLE QS[3] ; extern QADMSTATS g_s[3] ; extern CString g_que[3] ,- ttifdef _DEBUG ttundef THIS_FILE static char BASED_CODE THIS_FILE[] = FILE ; ttendif
///////////////////////////////////////////////////////////////////////////// // CdataDlg dialog
CdataDlg: : CdataDlg (CWnd^ pParent /=NULL^/) : CDialog (CdataDlg :: IDD, pParent)
//{ (AFX_DATA_INIT (CdataDlg)
// NOTE: the ClassWizard will add member initialization here //} }AFXJDATA_INIT
void CdataDlg: :DoDataExchange (CDataExchange^ pDX)
{
CDialog: : DoDataExchange (pDX) ; // { (AFX_DATA_MAP (CdataDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here //} }AFX_DATA_MAP
Figure imgf000238_0001
SMBUF m; void CdataDlg: :ScreenInit () (
CString s,ss; Q00236 int i, gotsize,- pOFORM po = (pOFORM) &m . mdata,- if (m_sub_mode == QADM_REQ_COM_DATA) s. Format ("%s %4d Commited %20d Uncommited entries" , LPCTSTR (g_que [m_ic g_s [m_id] .committed_entries, g_s [m_id] .pending_gets + g_s [m_id] .t_ else s.Format("%s %4d Uncommited %20d Commited entries" , LPCTSTR (g_que [m_id] ) , g_s [m_id] .pending_gets + g_s [m_id] .pending_puts, g_s [m_id] . committed ent SetDlgltemText ( IDCJTITLE, LPCTSTR (s) ) ;
CListBox* lb = (CListBox*) GetDlgltem (IDCJDATAL) ; lb->ResetContent () ,- for (i = 0; i < 200; i++) { m. mdata = i ,- if (QSUCCESS == QsendAndReceive (QS [m_id] , ADMINREQ_MODE, m_sub_mode ,
0, sizeof (int) , m. mdata, sizeof (m. mdata) , m. mdata, kgotsize, &m.msgh) ) ss = "%3d\t%s\t%s\t%s"; if (gotsize == sizeof (OFORM) ) { s .Format (LPCTSTR (ss) , i, po->cust , po->item, po- >qty , 0) ,- lb->InsertString (-1, s) ; } else if (gotsize) ( s .Format ( "%3d -\t%s" , i,m. mdata) ; lb->InsertString (-1, s) ; } else ( break;
ttdefine FORMATNAME "c : \\q\\formats . txt " char IsAddr(char c) { int off = 0 ,- if (strstr (c, "msgh") ) { if (strstr (c, "size") ) return((char ) m. msgh. size) } else if (strstr (c , "mdata" ) ) ( sscanf (c, "%♦ [" [] \ [%d" , off ) ,- return ( (m. mdata + off)) ;
} return (0) ;
} typedef struct fmts { // Thread parameters void* testa; int testv; char fmt [100 void* a [10] ; fmts* nex ,-
} FMTS , *pFMTS ; void clearf mt ( pFMTS p) ( p- >testa = NULL; p- >testv = 0 ; *p- >fmt = 0 ; for ( int i=0 ; i < 10 ; i++ ) p- >a [i] = NULL ; 00 0 2 3 7 p->next = 0; }
FMTS fmts; void ParseFormats () ( char line [LINESIZE] ,- char test [LINESIZE] ; char format [LINESIZE] ; char ops [LINESIZE] char opl [LINESIZE] char op2 [LINESIZE] char op [LINESIZE] ;
FILE *fp = fopen (FORMATNAME, "r") ; if ( I fp ) {
// SayC'Cant open the data formats file %s ", FORMATNAME ) ; return; } while (fgets (line, INESIZE, fp) ) ( if ( 3 == sscanf (line, "%[";];%[";];%[';]", test, format, ops) ) { if (strchr (test , ' # ') ) continue; if ( 3 != sscanf (test, "%s %s %s" , opl, op, op2) ) continue; if (strstr (opl, "size" ) ) fmts. testa = &m. msgh. size; sscanf (op2 , "%d" , &fmts . testv) ; strcpy (fmts . fmt , format) ;
} else {
; //Say ( "ReadParms : Ignoring: %s",line);
if (ferror (fp) ) {
// FailC'read error in parameters file %s" , PARMNAME) ,- clearerr (fp) ; fclose (fp) ,- }
///////////////////////////////////////////////////////////////////////////// // CdataDlg message handlers
BOOL CdataDlg: :OnInitDialog()
{
CDialog: : OnlnitDialog ( ) ; tτ_sub_mode = QADM_REQ_COM_DATA;
( (CButton *) GetDlgItem(IDC_CMT) ) ->SetCheck (TRUE) ;
Screenlnit () ; return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE
} void CdataDlg: :OnRefreshb()
{
Screenlnit () ,- void CdataDlg: :OnCmt 0 m_sub_mode = QADM_REQ_COM_DATA ; Screenlnit ( ) ;
void CdataDlg: :OnUncmt () m_sub_mode = QADM_REQ_UNCOM_DATA ; Screenlnit () ,-
void CdataDlg: :OnSearchb()
CKeySearch d; d.m_id = m_id; d . DoModal ( ) ;
// datadlg.h : header file //
///////////////////////////////////////////////////////////////////////////// // CdataDlg dialog class CdataDlg : public CDialog
(
// Construction public :
CdataDlg (CWnd* pParent = NULL); // standard constructor
// Dialog Data
//( (AFXJDATA (CdataDlg) enum { IDD = IDD_DATADIALOG } ;
// NOTE: the ClassWizard will add data members here //} }AFXJDATA int m_id; int m_sub_mode ,- void Screenlnit () ; // Overrides
// ClassWizard generated virtual function overrides
// ( (AFX_VIRTUAL (CdataDlg) protected : virtual void DoDataExchange (CDataExchange^ pDX) ,- // DDX/DDV sunport
//} }AFX_VIRTUAL
// Implementation protected :
Figure imgf000242_0001
// KeySearch h header file //
///////////////////////////////////////////////////////////////////////////// // CKeySearch dialog class CKeySearch public CDialog
{
// Construction public
CKeySearch (CWnd+ pParent = NULL), // standard constructor //void CM_swιtch(mt mode), // Dialog Data
//{ (AFXJDATA (CKeySearch) enum ( IDD = IDD_KEYSEARCH } ,
// NOTE the ClassWizard will add data members here //} }AFXJDATA //int m_mιn_ιnt , m_max_mt , m_at_mt , //CStrmg m_mm_str, m_max_str, m_at_st , int m_ιd, // 1-3 mt m_preds , mt m_pred_type [3] , t m_pιc, mt m_commιtted, mt m_uncommιtted, mt m_total_entπes , mt m_search_type , void OnCompChange ( mt pred), void ChangePredView (mt pred t act), void Copylnput (mt ored, mt mm, mt max),
// Overrides
// ClassWizard generated virtual function overrides
// { (AFX_VIRTUAL (CKeySearch) protected virtual void DoDataExchange (CDataExchange+ pDX) , // DDX/DDV support
//}}AFXJVIRTUAL
// Implementation protected ns
( ) { ) () () ( ) () ()
Figure imgf000243_0001
nt),
(UINT nFlags, CPoint point);
Figure imgf000244_0001
// mainfrm . cpp : implementation of the CMainFrame class // ttinclude " stdafx . h" ttinclude "qman . h" ttinclude "mainfrm . h" ttifdef _DEBUG ttundef THIS_FILE static char BASED_CODE THIS_FILE[] = FILE ; ttendif
///////////////////////////////////////////////////////////////////////////// // CMainFrame
IMPLEMENTJDYNCREATE (CMainFrame , CFrameWnd)
BEGIN_MESSAGE_MAP (CMainFrame, CFrameWnd) // { (AFX_MSG_MAP (CMainFrame)
// NOTE - the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see in these blocks of generated code
ON WM_CREATE() //J}AFXJMSG_MAP END_MESSAGE_MAP ( ) III///// II arrays of IDs used to initialize control bars
// toolbar buttons - IDs are command buttons static UINT BASED CODE buttons [] =
(
// same order as in the bitmap 'toolbar.bmp'
IDJFILE_NEW,
ID_FILE_OPEN,
ID_FILE_SAVE,
ID_SEPARATOR, ID_EDIT_CUT, ID_EDIT_COPY, ID_EDIT_PASTE,
ID_SEPARATOR, ID_FILE_PRINT, ID APP ABOUT,
}; ~ ~ static UINT BASED CODE indicators [] =
{
ID 3EPARAT0R, // status line indicator
ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID INDICATOR SCRL,
}; i IiIiCiMiaiiiniFiriaimieiicioiniisitriuicitimioni/dieiistmruc mtioinnimum II minimi mini i II nun
CMainFrame : : CMainFrame ( )
{
// TODO: add member initialization code here
CMainFrame : .- "CMainFrame ( )
{
} mt CMainFrame : :OnCreate (LPCREATESTRUCT IpCreateStruct)
( if (CFrameWnd: :OnCreate (IpCreateStruct) == -1) return -1; if ( Im_wndToolBar. Create (this) ||
!m_wndToolBar.LoadBιtmap(IDR_MAINFRAME) | | ! m_wndToolBar . SetButtons (buttons , sizeof (buttons) /sizeof (UINT) ) )
(
TRACEO ( "Failed to create toolbar\n"); return -1; // fail to create }
/ Derek's remove tool bar ♦/ m_wndToolBar . ShowWindow (SW_HIDE) ; if ( Im_wndStatusBar. Create (this) ||
I _wndStatusBar . Setlndicators ( indicators , sizeof (indicators) /sizeof (UINT) ) )
{
TRACEO ( "Failed to create status bar\n"); return -1; // fail to create }
// TODO: Delete these three lines if you don't want the toolbar to // be dockable m_wndToolBar.EnableDockιng(CBRS_ALIGN_ANY) ; EnableDockmg(CBRS_ALIGN_ANY) ,- DockControlBar (&m_wndToolBar) ;
// TODO: Remove this if you don't want tool tips m_wndToolBar . SetBarStyle (m_wndToolBar . GetBarStyle ( ) | CBRS TOOLTIPS I CBRS FLYBY) ; return 0;
}
///////////////////////////////////////////////////////////////////////////// // CMainFrame diagnostics ttifdef JDEBUG void CMainFrame : :AssertValid () const
{
CFrameWnd: : AssertValid ( ) ,-
} void CMainFrame :: Dump (CDumpContextS dc) const
{
CFrameWnd: :Dump(dc) ;
} ttendif //JDEBUG ///////////////////////////////////////////////////////////////////////////// // CMainFrame message handlers
// mamfrm . h : interface of the CMainFrame class
//
///////////////////////////////////////////////////////////////////////////// class CMainFrame public CFrameWnd
{ protected. // create from serialization only
CMainFrame ( ) ;
DECLAREJDYNCREATE (CMainFrame)
// Attributes public :
// Operations public .
// Overrides
// ClassWizard generated virtual function overrides //( (AFXJVIRTUA (CMainFrame) //} }AFXJVIRTUAL
// Implementation public virtual ~CMainFrame 0 , ttifdef JDEBUG virtual void AssertValid ( ) const, virtual void Dump (CDumpContextk dc) const, ttendif protected // control bar embedded members CStatusBar m_wndStatusBar, CToolBar m_wndToolBar ,
// Generated message map functions protected:
//{ (AFX_MSG(CMainFrame) afx_msg int OnCreate (LPCREATESTRUCT IpCreateStruct),
// NOTE - the ClassWizard will add and remove member functions h // DO NOT EDIT what you see m these blocks of generated code //} }AFX_MSG DECLARE MESSAGE MAP ( )
}; ///////////////////////////////////////////////////////////////////////////// // KeySearch . cpp : implementation f i le // ttinclude " stdafx . h" ttinclude "qman . h" ttinclude " KeySearch . h" ttdef ine QJLIB ttinclude " qlib . h " ttinclude " qadmm . h " ttinclude " orderfm . h" ttinclude " rt h "
ttifdef _DEBUG ttdef ine new DEBUG_NEW ttundef THISJFILE static char THIΞ_FILE [ ] = FILE , ttendif ttdefine KEY IMER 106 extern lpQHANDLE QS[3], extern QADMSTATS g_s[3]; extern CStrmg g_que[3]; extern IpSMBUFH sm_base; extern mt g_pιc [3+3+3] ,
///////////////////////////////////////////////////////////////////////////// ttdefine ID_OBJS 9 mt IDCJKPICS [8] = { IDCJQNONE1 , IDC_QD0WN1 , IDCJQΞTOP1 , IDC_QN0PUT1 , IDC_QNOGET" enum IDTYPE (COMP, MIN, AT, MAX, AND, OPA, OPB, OPC, OPD} , mt g id [3] [ID OBJS] = IDC_COMP_CBl , IDC_MIN_CB1 , IDC_AT_CB1 , IDCJMAXJCB1 , IDC_A IDC_COMP_CB2 , IDC_MIN_CB2 , IDC_AT_CB2 , IDC_MAX_CB2 , IDC_A IDC COMP CB3,IDC MIN CB3 , IDC AT CB3 , IDC MAX CB3 , IDC A
// List of items to get big fonts extern CFont g_text font, mt ALL_TEXT_S[] = flDC_ALL_R, IDC_COM_R, IDC_UNCOM_R, IDC_MODE, IDOK, IDSEARCHB, IDC_ m II iCK/ieyiiSe/aimrchid i III ialo ig ii iiiinniii/niiiiimn/iiiiii/i/iii/iiiiiii
CKeySearch: : CKeySearch (CWnd* pParent /*=NULL*/) : CDialog (CKeySearch: : IDD, pParent)
{
//{ (AFX_DATA_INIT (CKeySearch)
// NOTE, the ClassWizard will add member initialization here
//} }AFX DATA INIT
void CKeySearch: : DoDataExchange (CDataExchange* pDX)
(
CDialog: : DoDataExchange (pDX) ;
//( {AFX_DATA_MAP (CKeySearch)
// NOTE, the ClassWizard will add DDX and DDV calls here //}}AFX DATA AP
) ) ) ) ) ) ) ) )
Figure imgf000250_0001
// CKeySearch message handlers
BOOL CKeySearch: :OnInitDialog()
{
CDialog: : OnlnitDialog () ,- int i , id; m_preds = 1 ,- m_pred_type [0] = m_pred_type [1] = m_pred_type [2] = INT_SEARCH_TYPE; for (id = 1; id < OPA; id++)
GetDlgItem(g_id[0] [id] ) ->EnableWindo (FALSE) ; m_pic = (g_pic [m_id] + 1) % 8;
((CButton ♦) GetDlgItem(IDC_ALL_R) ) - >SetCheck (TRUE) ,- m_search_type = SEARCH_ALL_ENT ; m_committed = -1; m_uncommitted = - 1 ; m_total_entries = -1;
SetDlgltemText (IDC_MODE, "View " + g_que [m_id] + " Entries" ) ;
SetTimer (KEYTIMER, 1000, NULL) ; // 4 sec
i = 0; whi1e (ALL_TEXT_S [ i ] )
GetDlgItem(ALL_TEXT_S [i++] ) ->SetFont (&g_text_font )
return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE
mt Strmg2Tιme (const char s) ( // Thu Nov 30 17 30 00 1995 char mon [80] , mt mday, hr , mn, sc, yr, args, tm TM,
// If it starts with a day skip it sscanf (s, "%s" ,mon) , if (strstr ("Mon Tue Wed Thu Fri Sat Sun", mon)) s = s + 4, args = sscanf (s , "%s %d %d %d %d %d" , mon, kmday, &hr, &mn, &sc, &yr) if 1 strcmp (mon , " Jan ' TM tm_mon 0, else if 1 strcmp (mon , " Feb ' TM tm_mon 1, else if 1 strcmp (mon , " Mar ' TM tm_mon 2, else If 1 strcmp (mon , "Apr ' TM tm_mon 3, else if 1 strcmp (mon , " May' TM tm_mon 4, else If 1 strcmp (mon , " Jun ' TM tm_mon 5, else if 1 strcmp (mon , " Jul ' TM tm_mon 6, else If 1 strcmp (mon , "Aug ' TM tm_mon 7, else if 1 strcmp (mon , " Sep ' TM tm_mon 8, else if 1 strcmp (mon , "Ocf TM tm_mon 9, else if 1 strcmp (mon , " NoV TM ttr non 10, else if 1 strcmp (mon , " Dec ' TM tm mon 11, else TM tm mon = 12 if ((args == 6) && (TM tm_mon '= 12))
TM tm_sec = sc,
TM tm_mm = mn,
TM tm_hour = hr,
TM tm_mday = mday,
TM tm_year = yr - 1900,
TM tm_ιsdst = -1, return ( ktime (&TM) ) , } else return ( -1) ,
void Tιme2Strmg (mt time, char s, mt prmtday) ( if (prmtday) strcpy (s, ctime ( (tirnejt^) (ktime) ) ) , else strcpy (s, (ctime ( (timejt*) (&tιme) ) + 4) ) , // dont print day s[strlen(s) - 1] = 0, } void CKeySearch OnCompChange ( mt pred) ( CString type_str,
GetDlgltemText (g_ιd[pred] [COMP] , type_str) , mt comptype = INT_SEARCH_TYPE , if (type_str == "String") comptype = STR_SEARCHJTYPE, if (type_str == "Short") comptype = SHORT_SEARCHJTYPE , m_pred_type [pred] = comptype,
CComboBox * CBat = (CComboBox ) thιs->GetDlgItem (g_ιd [pred] [AT] ) , CComboBox CBmm = (CComboBox ) thιs->GetDlgItem (g_ιd [pred] [MIN] ) , CComboBox CBmax = (CComboBox ) thιs->GetDlgItem (g_ιd [pred] [MAX] ) ,
CBat->ResetContent ( ) , CBmm->ResetContent ( ) , CBmax- >ResetContent 0 , CBmm- >AddStnng ( " " ) , CB in- >AddStrmg ( ") ; CBmin- >AddStrmg ( ANY" ) CBmax- >AddStrmg ( ") ; CBmax- >AddStrmg ( ") ; CBmax- >AddStrmg ( ANY") if (type_str == "Time") ( char tιm[80] ,-
Tιme2Strιng (SHAREDATA (time) tim, 0) ,- CBat->AddStrmg("TIME") ;
CBmin- >SetCurSel (-1) ; CBmm->SetWιndowText (tim) ; // CBmin- >ReplaceSel (tim) ,
CBmin- >AddStrmg (tim) ; // add to edit box too?
CBmax- >AddStrmg (tim) ,- // add to edit box too? } else if (comptype == STR_SEARCH_TYPE) {
CBat->AddStrmg( "CUSTOMER") ;
CBat->AddStrmg("ITEM") ,-
CBat ->AddString ( "to_server" ) ;
CBat - >AddStrmg ( " tojlogical " ) , } else if (comptype == INT_SEARCH_TYPE) (
CBat ->AddStrmg( "UID") ,-
CBat->AddStrmg("TID") ;
CBat->AddStrmg("HOST") ,
CBat - >AddStrmg ( " QUANTITY" ) ;
IpRT rt = RTROOT; while (rt = NextRT(rt)) (
CBmιn->AddStrmg(RT_NODE(rt) ) , CBmax- >AddStrmg (RT NODE(rt) ) ,
} } else if (comptype == SHORT_SEARCH_TYPE) { CBat->AddStrmg("MODE") ; CBat->AddStrιng("SUB_MODE") ,-
for (mt id = 1; id < IDJOBJS; ιd++)
GetDlgItem(g_ιd[pred] [id] ) ->EnableWmdow (TRUE) ; GetDlgltem(IDSEARCHB) - >EnableWιndow (TRUE) ;
// GetParεntFrame () ->SetMessageText ("") ,- cedit SetDlgltemText (IDC_SERSTAT, "") ;
((CComboBox *) thιs->GetDlgIte (g_ιd [pred] [AT] ) ) - >SetCurSel (0) ; ((CComboBox *) thιs->GetDlgIte (g_ιd [pred] [MAX] )) ->SetCurSel (0) ((CComboBox *) this- >GetDlgItem(g_ιd [pred] [MIN] ) ) ->SetCurSel (0)
void CKeySearch- OnSelchangeCompCbl 0 fOnCompChange ( 0 ) void CKeySearch: OnSelchangeCompCb20 {OnCompChange ( 1 ) void CKeySearch: OnSelchangeCompCb30 (OnCompChange (2) void CKeySearch: : ChangePredView (mt pred, mt act)
( mt id ; for ( id = 0 ; id < ID_OBJS ; ιd++ ) 000250 GetDlgItem(g_ιd [pred] [id] ) - >ShowWmdow (act ) , for (id = 1, id < OPA, ιd++)
GetDlgItem(g_ιd[pred] [id] ) ->EnableWmdow (FALSE) , if (act == SWJHIDE) for (id = 0, id < AND, ιd++)
((CComboBox *) this- >GetDlgItem (g_ιd [pred] [id] ) ) - >SetCurSel ( -1) , if (act == SW_HIDE ) ( // Get rid of the ghost of the combo box MFC rjug'? thιs->Invalιdate ( ) , thιs->UpdateWmdow () ,
void CKeySearch OnAndl ( ) if (m_preds == 1) ( ChangePredView (l,SW_SHOW) , m_preds = 2 , else { ChangePredView (1, SWJHIDE) , ChangePredVie ( 2, SWJHIDE) , m_preds = 1 ,
} void CKeySearch OnAnd2 ( ) if (m_preds == 2) { ChangePredVie (2, SW_SHOW) , m_preαs = 3 , } else (
ChangePredView (2, SWJHIDE) , m_preds = 2 ,
}
} void CKeySearch Copylnput (mt pred, mt from, mt to)
CString s, mt pos,
GetDlgltemText (g_ιd[pred] [from] ,s GetBuf f er (100 ) , 100 ) , s ReleaseBuffer () , pos = ((CComboBox ) this- >GetDlgItem (g_ιd [pred] [to] ))- >GetCurSel 0 , ((CComboBox ♦) thιs->GetDlgItem (g_ιd [pred] [to] ) ) - >DeleteStrmg (0) ,
( (CComboBox ) thιs->GetDlgItem(g_ιd[pred] [to] ) ) -> Inserts tr ing (0 , s) , ( (CComboBox ) thιs->GetDlgItem(g_ιd[pred] [from] ) ) ->DeleteStrιng (1) , ( (CComboBox ♦) this ->GetDlgI tern (g_ιd [pred] [from] ) ) - >InsertStrmg (1, s) if (pos == 0) ( (CComboBox *) thιs->GetDlgItem(g_ιd[pred] [to] ) ) - >SetCurSel (0)
} void CKeySearch OnEditchangeMmCbl ( ) [Copylnput (0, MIN, MAX) , void CKeySearch OnEdιtchangeMmCb2 ( ) Copylnput (1, MIN, MAX) , void CKeySearch :OnEdιtchangeMmCb30 (Copylnput (2, MIN, MAX) , void CKeySearch OnEditchangeMaxCbl ( ) Copylnput ( 0 , MA , MIN) ; void CKeySearch OnEdιtchangeMaxCb2 () Copylnput ( 1 , MAX, MIN) , void CKeySearch 0nEdltchangeMaxCb3 ( ) Copylnput (2, MAX, MIN) ,- void CKeySearch- :OnSearchb ()
(
SMBUF b,B; QADMSEL key, OFORM order;
CString ss , s , at_str , mιn_str , max_str; mt ι,at_ιnt, sz, matches,
GetDlgltem(IDSEARCHB) ->EnableWmdow (FALSE) ;
CListBox* lb = (CListBox*) GetDlgltem ( IDC_SEARCHJLB) ; lb->ResetContent ( ) ;
SetDlgltemText ( IDC_SERSTAT, "") ;
// lb->SetTabStops (100) ; key . num_preds = m_preds ; key. search_type = m_search_type ; // SEARCH_ALL_ENT for (mt p = 0, p < m_preds ; p++) (
// Set mm and max values mm_str = " " ; max_str = " " ,
GetDlgltemText (g_ιd[p] [MIN] , mm_str . GetBuf fer ( 100 ) 100)
GetDlgltemText (g_ιd[p] [MAX] , max_str . GetBuffer ( 100 ) 100)
GetDlgltemText (g_ιd [p] [AT] , at_st . GetBuffer ( 100) , 100) , mm_str .ReleaseBuf fer () ,- max_str . ReleaseBuffer ( ) ; at_str .ReleaseBuffer 0 ; at_mt = GetDlgltemlnt (g_ιd[p] [AT] , NULL, TRUE) ; strcpy (key .preds [p] . mιn_str_val , LPCTSTR (mm_str) ) ; strcpy (key .preds [p] .max_str_val , LPCTSTR (max_str) ) ,- key. preds [p] .mm_ιnt_val = GetDlgltemlnt (g_id [p] [MIN] , NULL, TRUE) ; // min l key. preds [p] .max_mt_val = GetDlgltemlnt (g_ιd [p] [MAX] , NULL, TRUE) ; // max l key. preds [p] .mm_sh_val = key. preds [p] .mm_mt_val; // mm short key. preds [p] .max_sh_val = key .preds [p] .max_mt_val ,- // max short
if (min_str == "ANY" ) ( key . preds [p] . mιn_swιtch = 0 ,- key . preds [p] . mm_str_len = 0 ; } else ( key . preds [p] . mm_swιtch = 1 ; key . preds [p] . mm_str_len = strlen (key . preds [p] . mm_str_val ) ;
if (max_str == "ANY" ) ( key . preds [p] . max_swιtch = 0 ; key . preds [p] . max_str_len = 0 ; } else ( key . preds [p] . max_swιtch = 1 ; key . preds [p] . max_strjlen = strlen (key . preds [p] .max_str_val )
if (at_str == "TIME " ) { //char t ιm [ 80] , if (max str == "NOW" ) 000252 key. preds [p] .max_mt_val = SHAREDATA (time) ; if (d = Strιng2Tιme (LPCTSTR (max_str) ) ) ' = -1) key. preds [p] .max_mt_val = 1, if (mm_str == "NOW") key. preds [p] .mm_mt_val = SHAREDATA (time) ; if (d = Strmg2Tιme (LPCTSTR (mm_str) ) ) != -1) key .preds [p] .mm_mt_val = l ,-
// Tιme2Strmg (key. preds [p] . mιn_mt_val , tim, 1) ; // s .Format ( "Time value . %s ", tim) ; // SetDlgltemText (IDC_SERSTAT,s) ,
if (at_str == "HOST") { if d = Name2IP (LPCTSTR (max_str) ) ) key preds [p] .max_mt_val = I, if (l = Name2IP (LPCTSTR (mm_str) ) ) key preds [p] .mm_ιnt_val = l ,-
// Find the offset
Figure imgf000255_0001
) &b. msgh. time) (char *) Scb.msgh) ,
If (at_ str "MODE") at_ mt (char ♦) &b msgh. mode) (char ) Scb.msgh) , if (at_ str " SUB_MODE" ) at mt (char *) &b.msgh. sub_mode) (char *) &b.msgh) ,
If (at str "UID") at_ mt (char *) &b msgh. mid uid) (char ) Scb.msgh) ,
If (at str "TID") at_ _ιnt (char *) &b. msgh. mid. tid) (char ) &b.msgh) , if (at _str "HOST") at. mt (char ♦) &b. msgh. mid. host) (char ) &b.msgh) ;
If (at str "SIZE") at_ _mt (char ♦) &b. msgh. size) (char *) Scb.msgh) ;
If (at _str " to_server" ) at_ mt (char ♦) kb.msgh. to_server) (char *) ϋb.msgh) ; if (at str "to_logιcal") at mt (char ♦) Scb.msgh. to__logιcal) (char *) Scb.msgh) , if (at_str == "CUSTOMER") at_mt = sizeof (MSGH) + ((char ) Scorder . cust ) - ( (char ) Scorder) ,- if (at_str == "ITEM") at_mt = sizeof (MSGH) + ((char ) border, item) - ( (char *) Scorder) ; if (at_str == "QUANTITY") at mt = sizeof (MSGH) + ((char ) korder.qty) - ((char *) border) ;
key. preds [p] .offset = at_mt; key. preds [p] .predjtype = m_pred_type [p] ;
// Get the list of key matches if (QSUCCESS == QsendAndReceive (QS [m_ld] , ADMINREQ_MODE, QADMJREQ_SEL_DATA,
0, sizeof (key) , (char ) Sckey, sizeof (b .mdata) , b mdata, &sz , Scb .msgh) ) { lpMID md = (lpMID) b. mdata, matches = sz / sizeof (MID) , if (matches > 0) { char h = IP2Name (md- >host ) ; for (l = 0, l < matches , ι++) ( ss Format ( "%s ( d, %d) " , IP2Name (md->host ) , md- >uιd, md- >tιd) , s Format("%4d \t%s",ι+l,ss ) , lb- >InsertStrιng ( -1 , s) , md = (lpMID) ( (char ) md + sizeof (MID) ) ,
} else ( lb->InsertStrmg (-1, "No messages") ; } lb- >UpdateWmdow ( ) , //Sleep(200) , md = (lpMID) b mdata, lpOFORM po = (lpOFORM)B. mdata, for d = 0; l < matches ; ι++) ( memcpy (B .mdata, md, sizeof (MID) ) , // Copy one mid s. Format ("%d Messages Reading %d" , matches , l) , SetDlgltemText (IDC_SERSTAT, s) , GetDlgItem(IDC_SERSTAT) - >UpdateWιndow () , if (QSUCCESS == QsendAndReceive (QS [m_ιd] , ADMINREQJMODE, QADMJREQJMSG, 0, sizeof (mid) ,B .mdata, sizeof (B. mdata) , B mdata, Scsz , ScB .msgh) ) { ss .Format ("%s (%d, %d) " , IP2Name (md->host) , md- >uιd, md- >tιd) , if (B msgh. size == sizeof (OFORM) ) s Format("%4d \t%s\t%-8s\t%2d %-10s",ι + 1 , ss , po- >cust ,po- >qty , po else if (sz) s. Format ("%4d \t%s\t%s",ι + 1, ss,b. mdata) , else s Format("%4d \t%s\t<<Empty>>" , I + l,ss), lb->DeleteStrmg d) , lb->InsertStrιng d, s) , } else { s Format ("%d Error requesting %s(%d,%d)",ι + 1 , IP2Name (md->host) , md- SetDlgltemText (IDC_SERSTAT, s) ,- break; // Stop here
} md = (lpMID) ( (char Jmd + sizeof (MID) ) ;
}
} else s .Format ("Error - no reply") , if ( I strstr (LPCTSTR (s) , "Error") ) s.Format(" d Matches " , matches) , SetDlgltemText ( IDC_SERSTAT, s) ;
Sleep(500) ;
GetDlgltem ( IDSEARCHB) - >EnableWmdow (TRUE)
}
void CKeySearch: :OnTimer (UINT nIDEvent)
( if (nIDEvent == KEYTIMER) ( int com, uncom; CString s ; i f ( ( g_pic [m_id] ! = m_pic ) ) {
GetDlgl tem ( IDCJKPI CS [g_pic [m_id] ] ) - >ShowWindow ( SW_SHOW) ; GetDlg l tem ( IDCJKPI CS [m_pic ] ) - >ShowWindow ( SW_HIDE ) ; m_pic = g_pic [m_id] ,-
// Set Title this- >SetWindowText ( "View " + g que [ id] ) ; } if (recommitted != (com = g_s [m_id] . committed__entries) ) ( s . Format ( "%3d Committed entries.", (recommitted = com)); SetDlgltemText (IDC COM R,s);
} " " if (m_uncommitted != (uncom = g_s [m_id] . pending_gets + g_s [m_id] .pending p s . Format ( "%3d Uncommitted entries.", (m_uncommitted = uncom)); ~~
SetDlgltemText (IDC UNCOM R,s);
} if (m_total_entries != (com + uncom)) { s . Format ( "All %d entries.", (m_total_entries = com + uncom));
SetDlgltemText (IDC_ALLJR,s) ,-
} else
CDialog: : OnTimer (nIDEvent ) ,-
void CKeySearch: :OnAllR()
( m_search_type = SEARCH_ALL_ENT; } void CKeySearch: : OnComR 0
( m_search_type = SEARCHJCOMJENT ; } void CKeySearch: : OnUncomR 0
( m_searchjtype = SEARCH_UNCOMJENT ; } void CKeySearch: : OnRButtonDown (UINT nFlags, CPoint point)
(
GetParentFrame () ->SetMessageText (" ") ; this- >Invalidate ( ) ,-
CDialog: : OnRButtonDown (nFlags , point) ; // qman cpp Def ines the class behaviors for the application // ttinclude " stdafx h" ttinclude " qman h" ttinclude "mamfrm h " ttinclude " qmandoc h " ttinclude " qmanview h" ttifdef JDEBUG ttundef THISJFILE static char BASED_CODE THISJFILE [ ] = _FILE , ttendif i I/ /iCiQ/miainiAipip///// in 1//1/111/1111//////111///11//11 nm / ii ///mi ii mn /in//
BEGIN_MESSAGE_MAP (CQmanApp, CWinApp)
// ( (AFX_MSG_MAP (CQmanApp)
ON_COMMAND ( ID_APP_ABOUT , OnAppAbout )
// NOTE - the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see in these blocks of generated code
//} }AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp OnFileNew)
ON_COMMAND(ID_FILEJPEN, CWinApp OnFileOpen)
// Standard print setup command
ON_COMMAND(IOJFILE_PRINT_SETUP, CWinApp OnFilePrmtSetup) END_MESSAGE_MAP ( ) iiiiiiiiiiiiim iiimiiiim m/m miiiiiiim mn i nm mm/11111 mn
I I CQmanApp construction
CQmanApp CQmanApp ( )
// TODO add construction code here,
// Place all significant initialization Initlnstance }
///////////////////////////////////////////////////////////////////////////// // The one and only CQmanApp object
CQmanApp theApp ,
///////////////////////////////////////////////////////////////////////////// // CQmanApp initialization
BOOL CQmanApp Initlnstance ( )
(
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
Enable3dControls () ,
LoadStdProflleSettmgs () , // Load standard INI file options (including
// Register the application's document templates Document templates // serve as the connection between documents, frame windows and views.
CSingleDocTemplate^ pDocTemplate,- pDocTemplate = new CSingleDocTemplate (
IDR_MAINFRAME,
RUNTIME_CLASS(CQmanDoc) ,
RUNTIME_CLASS (CMainFrame) , // main SDI frame window
RUNTIME_CLASS (CQmanView) ) ; AddDocTemplate (pDocTemplate) ;
// create a new (empty) document OnFileNe ; if (m lpCmdLine[0] != '\0')
(
// TODO: add command line processing here
return TRUE;
}
///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog public :
CAboutDlg ( ) ,-
// Dialog Data
//{ (AFXJDATA (CAboutDlg) enum { IDD = IDD_ABOUTBOX } ; //} }AFXJDATA
CFont m_title_font; // Implementation protected: virtual void DoDataExchange (CDataExchange^ pDX) ; // DDX/DDV support
// { (AFX_MSG (CAboutDlg) virtual BOOL OnlnitDialog ( ) ;
//}}AFX__MSG
DECLAREJESSAGE_MAP ( )
CAboutDlg: : CAboutDlg () : CDialog (CAboutDlg :: IDD)
//{ (AFXJDATA_I IT (CAboutDlg) //} }AFX_DATA_INIT
void CAboutDlg: :DoDataExchange (CDataExchange^ pDX)
CDialog: : DoDataExchange (pDX) ; //{ (AFX_DATA_MAP (CAboutDlg) // } }AFX_DATA_MAP
BEGIN_MESSAGE_MAP (CAboutDlg, CDialog) // { (AFX_MSG_MAP (CAboutDlg) //} }AFX_MSG_MAP END_MESSAGE_MAP ( )
// App command to run the dialog void CQmanApp OnAppAbout 0
CAboutDlg aboutDlg, aboutDlg DoModal ( ) , }
///////////////////////////////////////////////////////////////////////////// // CQmanApp commands
BOOL CAboutDlg OnlmtDialog ( )
(
CDialog OnlmtDialog 0 ,
LOGFONT If, memset (Self, 0, sizeof (LOGFONT) ) , strcpydf IfFaceName , "Monotype Corsiva"), If lfHeight = 24, m_tιtle_font CreateFontlndirect (Self ) ,
GetDlgltem (IDC_AB0UT1) ->SetFont (&m_tιtle_font ) ,
// TODO Add extra initialization here return TRUE, // return TRUE unless you set the focus to a control // EXCEPTION OCX Property Pages should return FALSE
// qman.h : main header file for the QMAN application // ttifndef AFXWINJH tterror include ' stdafx . h ' before including this f i le f or PCH ttendif ttinclude " resource . h " / / main symbols
11111111111 II I II 1171111 II 1111111111111111 II 11117 II 1111111 / 11111111 / 1111111) 11
11 CQmanApp :
// See qman . cpp for the implementation of this class
// class CQmanApp : public CWinApp
( public :
CQmanApp ( ) ;
// Overrides
// ClassWizard generated virtual function overrides
// { ( FXJVIRTUAL (CQmanAp ) public : virtual BOOL Initlnstance () ;
//} } AFXJVIRTUAL
// Implementation
//( (AFX_MSG (CQmanApp) afx_msg void OnAppAbout 0 ,-
// NOTE - the ClassWizard will add and remove member function // DO NOT EDIT what you see in these blocks of generated code
//} }AFX_MSG
DECLARE MESSAGE MAP ( )
/////////////////////////////////////////////////////////////////////////////
// qmandoc . cpp : implementation of the CQmanDoc class // ttinclude " stdafx . h" ttinclude "qman . h " ttinclude " qmandoc . h " ttifdef _DEBUG ttundef THISJFILE static char BASED_CODE THISJFILE [ ] = FILE ,- ttendif
///////////////////////////////////////////////////////////////////////////// // CQmanDoc
IMPLEMENT_DYNCREATE (CQmanDoc , CDocument)
BEGINJMESSAGEJMAP (CQmanDoc, CDocument) // ( (AFXJMSG_MAP (CQmanDoc)
// NOTE - the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see m these blocks of generated code //} }AFX_MSG^MAP END_MESSAGE_MAP ( ) **
////7/ 111111111111111 I 11111111111 III7 I 1 II 111111711111111111111111111111111
II CQmanDoc construction/destruction
CQmanDoc : : CQmanDoc ( )
(
// TODO: add one-time construction code here
CQmanDoc : : ~CQmanDoc ( )
BOOL CQmanDoc : : OnNewDocument ( )
{ if (I CDocument : : OnNewDocument ( ) ) return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document) return TRUE; }
///////////// / // ///////////////////////////////////////// //////////////////// // CQmanDoc serialization void CQmanDoc : : Serialize (CArchiveSc ar)
{ if ( ar . IsStoring O )
{
// TODO : add storing code here
} else // TODO: add loading code here
. >
///////////////////////////////////////////////////////////////////////////// // CQmanDoc diagnostics ttifdef JDEBUG void CQmanDoc : : AssertValid 0 const
(
CDocument: :AssertValid ( ) ;
} void CQmanDoc :: Dump (CDumpContextk dc) const
{
CDocumen : :Dump (dc) ;
} ttendif //_DEBUG
///////////////////////////////////////////////////////////////////////////// // CQmanDoc commands
0002G1 // qmandoc h interface of the CQmanDoc class
//
///////////////////////////////////////////////////////////////////////////// class CQmanDoc public CDocument
( protected // create from serialization only
CQmanDoc ( ) ,
DECLAREJDYNCREATE (CQmanDoc )
// Attributes oublic
/ / Operations public
/ / Overrides
// ClassWizard generated virtual function overrides
// ( (AFXJVIRTUAL (CQmanDoc) public virtual BOOL OnNewDocument ( ) ,
// } } AFXJVIRTUAL
// Implementat ion public virtual ~ CQmanDoc ( ) , virtual void Serialize ( CArchiveSc ar) , // overridden for document 1/0 tt i fdef JDEBUG virtual void AssertValid ( ) const , virtual void Dump ( CDumpContext c dc ) const , ttendif protected
// Generated message map functions protected
// { {AFX_MSG (CQmanDoc)
// NOTE - the ClassWizard will add and remove member functions h // DO NOT EDIT what you see in these blocks of generated code //}}AFX_MSG DECLARE MESSAGE MAP 0
}. minimum iiiiimmmmmimmmiiimm imimmmmmiii // qmanview h interface of the CQmanView class
//
///////////////////////////////////////////////////////////////////////////// class CQmanView public CFormView
( protected // create from serialization only
CQmanView ( ) ,
DECLAREJDYNCREATE (CQmanView) public
//{ (AFXJDATA (CQmanView) enum( IDD = IDDJQMAN_FORM },
// NOTE the ClassWizard will add data members here //} } AFXJDATA
// Attrioutes mt m_maxtrack, CString m_que[3] , public
CQmanDoc^ GetDocument () ,
// Operations oublic
// Overrides
// ClassWizard generated virtual function overrides
//{ (AFXJVIRTUAL (CQmanView) public virtual void OnlnitialUpdate () , protected virtual void DoDataExchange (CDataExchange* pDX) , // DDX/DDV support virtual BOOL OnPreparePrmting (CPrintlnfo* plnfo), virtual void OnBegmPrmtmg (CDC* pDC, CPrmtlnfo* plnfo), virtual void OnEndPrmtmg (CDC* pDC, CPrmtlnfo* plnfo), virtual void OnPrmt (CDC* pDC, CPrmtlnfo*), virtual void OnDrawfCDC^ pDC) ,
//} } AFXJ IRTUAL //void InitTrackBar (HWND hTrack, int IDMIN, mt TMIN, mt IDMAX, mt TMAX, in //DWORD Poll () , //DWORD CQmanView Poll 0 , void CQmanView OpenQue (mt l, mt IDCJQUES) ,
// meter painting void DrawKey ( ) , void GetMeterBoxes 0 , void TestMeters ( ) , void CQmanView LoadList (int QN, mt IDC_QUES), void CQmanView DrawMeterdnt i) , void CQmanView CmdLme (int pass), void CQmanView DrawKeyColor (mt ID, t HS , COLORREF COL),
// font
CFont m_tιtle_font ,
// Implementation public virtual "CQmanView 0 , ttifdef JDEBUG virtual void AssertValid ( ) const; virtual void Dump (CDumpContextk dc) const, ttendif protected .
// Generated message map functions
pScrollBar)
Figure imgf000266_0001
ttifndef JDEBUG / / debug version m qmanview cpp mime CQmanDoc* CQmanView : : GetDocument ( )
{ return ( CQmanDoc ♦ ) m_pDocument ; } ttendif
/////////////////////////////////////////////////////////////////////////////
// qmanview.cpp implementation of the CQmanView class //
ttinclude "stdafx.h" ttinclude "qman.h" ttinclude "qmandoc. h" ttinclude "qmanview.h" ttinclude "admmdlg.h" //ttinclude "datadlg.h" ttinclude "KeySearch. h'
//+++++++++++++ QLIB -++++++++++++++++++ ttinclude "qlib.h" ttinclude "qadmin.h" ttinclude "rt.h"
ttdefine MYTIMER 100 ttdefine TITLETIMER 101 ttdefine MINJPOLLJDLY 100 ttdefine MAX POLL DLY 5000
extern IpSMBUFH sm base, lpQHANDLE ~ QS[3] = |NUL , NUL , NULL} ;
QADMSTATS g_s[3+3], // 3 Current + 3 Old int g_startmg[3] ; // forces first N updates of meter
//HWND g_track[3] ,
HWND g_tmm[3] ,
HWND g_tmax[3] ;
HWND g_tlab[3] ;
CStrmg g_σue [ ] = { « » t « <• , » » ) ; int ALL TEXT[] = ( IDC_TMIN1 , IDCJTMIN2 , IDC_TMIN3 , IDC_TMAX1 , IDCJTMAX2 , IDC_TMAX3 , IDCJTLAB1 , IDC_TLAB2 , IDCJTLAB3 , IDC_ADMINB1 , IDC_ADMINB2 , IDC_ADMINB3 , IDC_DATAB1 , IDC_DATAB2 , IDCJDATAB3 , IDCJ2UES1 , IDCJ2UES2 , IDC_QUES3 , IDC EXIT, 0,0,0} ;
mt IDC_TMINS[] = IDCJTMIN1 , IDCJTMIN2 , IDCJTMIN3 , mt IDCJTMAXS [] = ( IDCJTMAX1 , IDCJTMAX2 , IDCJTMAX3 j ; mt IDCJTLABS [ ] = IDCJTLAB1 , IDC_TLAB2 , IDCJTLAB3 } ; mt IDC_METERS [] = ( IDCJ4ETER1 , IDC_METER2 , IDC_METER3 } ; int IDC__PICS [3] [8] = { ( IDC_QN0NE1 , IDC_QD0WN1 , IDC_QST0P1 , IDC_QN0PUT1 , IDC_QN0GET1
I IDCJQNONE4 , IDCJQDOWN4 , IDC_QΞTOP4 , IDC_QNOPUT4 , IDC_QNOGET4 ( IDCJQNONE5 , IDC_QDOWN5 , IDCJQSTOP5 , IDC_QNOPUT5 , IDC__QNOGET5 enum pics (QNONE, QDOWN, QSTOP, QNOPUT, QNOGET,QUP, QNOPG, QFULL} ; mt g_pιc [3+3 t-3] ; mt g_poll; mt g_pol l_delay = 2000 ,
CFont gjtext font ; typedef struct met // Thread parameters
CRect b rec;
CRect c_rec ;
CRect p rec ,-
CRect g__rec ;
CRect h_rec;
CRect f__rec; int commit , pendp, pendg, hole , f ee , min, max;
MET, pMET;
MET g_met [3+4]
//+++++++++++++ QLIB +++++++++++++++++++
ttifdef JDEBUG ttundef THISJFILE static char BASED_CODE THIS_FILE[] FILE ttendif
// CQmanView
IMPLEMENT DYNCREATE (CQmanView, CFormView)
Figure imgf000268_0001
///////////////////////////////////////////////////////////////////////////// // CQmanView construction/destruction
CQmanView: : CQmanView ()
: CFormView (CQmanView :: IDD)
{
//( (AFX_DATA_INIT (CQmanView)
// NOTE: the ClassWizard will add member initialization here // } }AFXJDATA_INIT
// TODO . add construct ion code here
CQmanView : : ~CQmanVιew ( )
void CQmanView : : DoDataExchange ( CDataExchange^ pDX)
(
CFormView: : DoDataExchange (pDX) ; //( (AFX_DATA_MAP (CQmanView)
// NOTE, the ClassWizard will add DDX and DDV calls here //} }AFX DATA MAP
) iiiinii nn III II
1/ CQmanView pr iint minginimum mi mini i III nm 11 II i mini mm mm
BOOL CQmanView: : OnPreparePrmtmg (CPrmtlnfo* plnfo)
// default preparation return DoPreparePrintmg (olnfo) ,- } void CQmanView. :θnBegmPrιntιng(CDC* /pDCV, CPrmtlnfo* /♦plnfoV)
// TODO: add extra initialization before printing } void CQmanView- :0nEndPnntιng (CDC+ /pDC^/, CPrmtlnfo* /*pInfo*/)
(
// TODO. add cleanup after printing
} void CQmanView : : OnPrιnt (CDC* pDC , CPrmt lnfo* )
(
// TODO: add code to print the controls
}
II CQmanView diagnostics ttifdef JDEBUG void CQmanView : : AssertValid 0 const
{
CFormView- :AssertValid 0 ;
} void CQmanView. : Dump (CDumpContextSc dc) const
{
CFormView: :Dump(dc) ,
}
CQmanDoc* CQmanView : :GetDocument ( ) // non-debug version is mime
{
ASSERT (m_pDocument->IsKmdOf (RUNTIMEJCLASS (CQmanDoc) ) ) ; return (CQmanDoc♦ ) m_pDocument ;
} ttendif //JDEBUG ///////////////////////////////////////////////////////////////////////////// // CQmanView message handlers void CQmanView : : OnExιt ( )
( g_poll = 0; // Stop the threads AfxGetMamWnd ( ) - >DestroyWmdow ( ) ;
// METER METER METER METER METER METER METER METER METER METER METER METER // METER METER METER METER METER METER METER METER METER METER METER METER // METER METER METER METER METER METER METER METER METER METER METER METER // // b_rec // + + + + // I Committ I Pending I holes I Free // // // p_rec h rec f rec
void CQmanView: : GetMeterBoxes 0 ( for (mt ι=0,-κ3;i++){
GetDlgltem ( IDCJMETERS [i] ) - >GetWιndowRect (Scg_met [l] .b_rec) ,- // Adgust coordantates for 0,0,l,b g_met [ . b_rec . right g_met [ l] . b_rec . lef t ; g_met [i . b_rec . bottom g_met [ i ] . b_rec . top ,- g_met [l . b_rec . left g_met [ l] . b_rec . top = 0; g_met [I . c_rec . left 0 ; // Commit always starts at 0,0 g_met [ l . f_rec . right g_met [l] . b_rec . right , // Free always ends at max g_met [ i c_rec . top g_met [I p_rec . top g_met [i g_rec . top g_met [ I h_rec . top g_met [ I f_rec . top = g_met [i] .b_rec.top,- // 0 g_met [i c_rec .bottom g_met d p_rec .bottom g_met [i g_rec. bottom g_met [i h_rec .bottom g_met [i f rec. bottom g_met [i] .b_rec .bottom; // All the same hight
void CQmanView: : DrawKeyColor (mt ID, mt HS, COLORREF COL) CRect c_rec,- CBrush *pCBrush; if ( HS == -1 ) pCBrush = new CBrush (COL) ; else pCBrush = new CBrush (HS, COL) ; GetDlgltem(ID) - >GetWindowRect (ScC_rec) ;
// Adjust coordantates for 0,0,l,b c_rec. right -= c_rec.left; c_rec . bottom -= c_rec.top; c_rec.left = c_rec . top = 0;
// The DC for the meter CDC* pCOLORDC = GetDlgltem ( ID) ->GetDC () ,-
// Select this brush, save the old CBrush pOldBrush = pCOLORDC- >SelectObject (pCBrush) ; pCOLORDC- >Rectangle (c_rec) ;
GetDlgltem (ID) ->Invalidate 0 ,- delete (pCBrush) ; ReleaseDC (pCOLORDC) ;
void CQmanVie :: DrawKey 0 {
DrawKeyColor ( IDCJKEYJCOM, -1, RGB(127,255,255) ) DrawKeyColor ( IDCJKEYJPENPUT , HS_BDIAGONAL, RGB (000 , 182 , 255) ) DrawKeyColor (IDC_KEY_PENGET, HSJFDIAGONAL, RGB (000 , 182 , 255) ) DrawKeyColor ( IDCJKEYJHOLE , HS DIAGCROSS, RGB (255 , 128 , 128) )
ttdefine MAXPIXELS g_met[i].b rec. right void CQmanView: :TestMeters () int c,pg,pp,h; // Pixel width of each rectangle for (int i=0; i<3 ,-i++) ( // If any change if ( (g_met [i] .commit g_s[i] . committed_entries) (g_met [i] .pendg g_s [i] .pending_gets ) (g_met [i] . pendp g_s [i] .pending_puts) | (g_met [i] . hole g_s [i] .holey_entries ) (g_met [i] . free g_s[i] .num_free_entries) (g met [i] .max g s[i] .max entries) ) { if (!g s[i] .max_entries) g_s[i] . max_entries=l ; // No divide by zero
// Update old values g_met[i] .commit = g_s [i] . committed_entries ; g_met [i] .pendg = g_s [i] .pending_gets ; g_met [i] .pendp = g_s [i] -pending_puts ; g_met [i] .hole = g_s [i] . holey_entries; g_met [i] . f ree = g_s [i] .num_f ree_entries ; g_met[i] .max = g_s [i] .max_entries ;
// c,pp,pg,h,f are points on a line between min, max scaled to ttpixe c = 0 + (MAXPIXELS * g_met [i] . commit ) /g_met [i] .max; pp= c + (MAXPIXELS * g_met [i] .pendp) /g_met [i] .max; pg=pp + (MAXPIXELS * g_met [i] .pendg) /g_met [i] .max; h =pg + (MAXPIXELS * g_met [i] .hole) /g_met [i] .max; // f = h + (MAXPIXELS g_met [ 1 ] . free) /g_met [ι ] . max ; // constant // Make 5 rectangles to f ill with colors
// g_met [ 1 . c_rec . left = 0 ; // constant g_met [1 . c_rec right = c ; g_met [ i p_rec . left = c ; g_met [ 1 . p_rec . right = pp ,- g_met [ 1 g_rec . left = pp ; g_met [ 1 g_rec . right = pg ; g_met [ 1 h_rec . lef t pg; g_met [ 1 h_rec . right h, g_met [ 1 f_rec.left = h; // g_met [ι f_rec. right = g_met [l] . max, // constant
DrawMeter d) ,
void CQmanView :: DrawMeter (mt l) (
// Create the Brush
CBrush *pCBrush = new CBrush( RGB ( 127 , 255 , 255) ),
CBrush *pPBrush = new CBrush ( HS_BDIAGONAL, RGB (000 , 182 , 255) ),
CBrush *pGBrush = new CBrush ( HS_FDIAGONAL, RGB ( 000 , 182 , 255 ) );
CBrush pHBrush = new CBrush ( HSJDIAGCROSS, RGB (255 , 128 , 128 ) ),
// The DC for the meter CDC^ pCOLORDC = GetDlgltem ( IDC_METERS [l] )- >GetDC () ,
// Create a PEN
// CPen pQPen = new CPen (PS_SOLID, 3 , RGB (0 , 0 , 255 ) ) ;
// CPen pOldPen = pXDC->SelectOb ect (pQPen) ;
// Select this brush, save the old CBrush pOldBrush = pCOLORDC- >SelectObject (pCBrush) ; pCOLORDC- >Rectangle (g_met [l] .c_rec) ; pCOLORDC- >SelectObgect (pPBrush) ,- pCOLORDC- >Rectangle (g_met [i] .p_rec) ,- pCOLORDC->SelectObηect (pGBrush) ; pCOLORDC- >Rectangle (g_met [l] .g_rec) ; pCOLORDC- >SelectObgect (pHBrush) , pCOLORDC- >Rectangle (g_met [l] .h_rec) ; pCOLORDC- >SelectStockObgect (WHITE_BRUSH) ,- pCOLORDC- >Rectangle (g_met [i] .f_rec) ;
pCOLORDC- >SelectOb] ect (ScpOldBrush) ; // Reset the brush GetDlgltem ( IDC_METERS [i] ) - invalidate ( ) ; delete (pCBrush) ; delete (pPBrush) ; delete (pGBrush) ; delete (pHBrush) ,- ReleaseDC (pCOLORDC)
/* //////////////////////////////////// // Init the track bar //
// 0 TPS 100 //
// I tl I //
// MIN MAX //
////////////////////////////////////
void InitTrackBar (HWND hTrack, HWND HMIN, int TMIN, HWND HMAX, int TMAX) ( CString s,-
//HWND hTrack = GetDlgltem ( ID) ->m_hWnd;
SendMessage (hTrack, TBM_SETRANGEMIN, TRUE, TMIN) ; '
SendMessage (hTrack , BM_SETRANGEMAX, TRUE , TMAX) ;
SendMessage (hTrack, TBM_SETTICFREQ, 1, TRUE) ;
SendMessage (hTrack, TBM_SETPOS , TRUE, TMIN) ,-
SendMessage (hTrack, TBM_SETSELSTART, TRUE, TMIN) ; // Select from start
// Track Bar lables
/Is . Format ("%d" , TMIN) ; SetDlgltemText (IDMIN, s) ;
// s. Format ("%d" ,TMAX) ; SetDlgltemText (IDMAX, s) ; s. Format ("%d" , TMIN) ; :: SendMessage (HMIN, WM_SETTEXT, 0 , (LPARAM) (LPCTSTR) s) s. Format ("%d" , TMAX) ; :: SendMessage (HMAX, WM_SETTEXT, 0 , (LPARAM) (LPCTSTR) s)
} */
DWORD PolKLPVOID qnum)
MSGH mh;
CString s,sl; int used = 1; // Clear the track bar if not in use int i = (int) (qnum) ; int repeated_error = 0 ; g_poll = l; while (g_poll) { if (QS[il) ( int sz; used++ ; if (QS [i] ->open_time)
: : SendMessage (g_tlab[i] , M_SETTEXT, 0 , (LPARAM) (LPCTSTR) "STARTING..." if (QSUCCESS >= (QsendAndReceive (QS [i] , ADMINREQ MODE, QADM_REQ_STATS, 0, sizeof (g_s [i] ) , (char *) &g_s [i] , Scsz, &mh) ) )J if ((mh.mode == ADMINREP_MODE || mh.mode == ACK_MODE ) k& (sz > 0
// Note: now, mode is ADMINREP_MODE if local . if ( !g_starting[i] ScSc !memcmp( S=g_s[i+3], &g_s [i] , sizeof (QADMSTAT goto skip; memcpy( &g_s[ι + 3] , S=g_s [i] , sizeof (QADMSTATS) ) , // set hιstory=cu if (g_startιng[ι] ) g_startmg [ι] - - , // stop forcing m repeated_error = 0 ;
// Assign a picture if (g_s [1] .qget_state ScSc g_s [1] . qput_state) g_pιc[l] = QUP; else if (g_s[i] .qget_state) g_pιc [1] = QNOPUT; else if (g_s [1] .qput_state) g_pιc(ι] = QNOGET; else g_pιc[ι] = QNOPG; if (g_s[ι] . num_f ee_entrιes == 0) g_pιc[l] = QFULL;
if (QS [l] ->open_tιme) QS [i] ->openjtιme = 0, // Get rid of "START s .Format ("%s :%s at %s has %d entries" , Scg_s [l] . physιcal_qname , &g_ si . Format ( "%d" , g_s [l] .max_entrιes) ; . : SendMessage (g_tlab [l] , WM_SETTEXT, 0 , (LPARAM) (LPCTSTR) s) ; : : SendMessage (g_tmax[ι] , WM_SETTEXT, 0 , (LPARAM) (LPCTSTR) si) ; : : SendMessage (gjtmm [l] , WM_SETTEXT, 0 , (LPARAM) (LPCTSTR) "0") ,
} else (
: : SendMessage (g_ lab [l] , WM_SETTEXT, 0 , (LPARAM) (LPCTSTR) "BAD REPLY // QS[ι] = NULL, if (repeated_error++ > 0) { g_pιc [l] = QDOWN; Sleep(5000) , } else g pic [l] = QSTOP;
} } else {
: .SendMessage (g_tlab[ι] , WMJSETTEXT , 0 , (LPARAM) (LPCTSTR) "COMM ERROR") // QS[l] = NULL; if (repeated_error++ > 0) { g_pιc [l] = QDOWN; Sleep(5000) ; } else g_pιc[i] = QSTOP;
> } else ( // No open que // if (g_que[ι] == "") // g_pιc[ι] = QNONE; if (used) { used = 0; // The track bar will now be clear me set (&g_s [l] ,0, sizeof (g_s [I] ) ) ; g_s [ι+3] .max_entrιes = 1;
//: :SendMessage(g_track[ι] , TBM_SETPOS , TRUE , 0 ) ;
//: .SendMessage (g_track[i] ,TBM_SETSELEND, TRUE, 0) ,-
. : SendMessage (g_tlab[ι] , WMJSETTEXT , 0 , (LPARAM) (LPCTSTR) "No Que") ;
: :SendMessage(g_tmm[l] , WM_SETTEXT, 0 , (LPARAM) (LPCTSTR) "") ■
.. SendMessage (g tmax[ι] , WM_SETTEXT , 0 , (LPARAM) (LPCTSTR) "") ,
skip: Sleep (g_poll_delay) ; _ } // While loop return (1) ;
void CQmanView- : CmdLme (mt pass)( CString parm, value, line, nlme; mt ι,poll; line = AfxGetApp ( ) - >mJlpCmdLme ,- while (2 <= d = sscanf (LPCTSTR (line) , "%s %s %["©]", parm.GetBuffer (100) , value .GetBuffer (100 ) , nlme . GetBuffer ( 100 ) ) parm.MakeUpper ( ) ; if (parm == "POLL") ( sscanf (LPCTSTR (value) , "%d" , fcpoll) ,- if ( (MIN_POLL_DLY <= poll) SSc (poll <= MAX_POLL_DLY) ) g poll delay = poll,
} ~* " if (parm == "1") {
CComboBox * CB = (CComboBox ) this- >GetDlgIte ( IDC_QUES1 ) , CB->SelectStrmg (-1, value) , OnSelchangeQuesl ( ) ;
} if (parm == "2") {
CComboBox * CB = (CComboBox *) this- >GetDlgItem ( IDC_QUES2 ) ,
CB- >SelectStrιng ( -1 , alue) ,
OnSelchangeQues2 () ,
} if (parm == "3") {
CComboBox * CB = (CComboBox ) this- >GetDlgItem ( IDC_QUES3 ) ,
CB->SelectStrmg(-l, value) ;
OnSelchangeQues30 ; } line = LPCTSTR (nlme) ; nlme = "";
mt g_poll_delay_old; void CQmanView: :OnTιmer (UINT nIDEvent)
// Select ICONS if (nIDEvent == MYTIMER) { for ( t l = 0;l<3;l++) { if (g_pιc[ι] '= g_pιc[ι+3] ) {
GetDlglte (IDC_PICS [l] [g_pιc [i] ] ) ->ShowWιndo (SW_SHOW) ; GetDlglte (IDC_PICS [ι] [g_pic d+3] ] ) ->ShowWιndo (SWJHIDE) g_pιc[ι+3] = g_pιc[ι] ;
TestMeters () ,
} else if (nIDEvent == TITLETIMER) { GetParentFrame ( ) - >SetWιndowText ( "QMAN" ) KillTimer (TITLETIMER) , DrawKey ( ) ,
} else
CFormView OnTimer (nIDEvent ) ,
void CQmanView LoadListdnt QN, t IDCJQL) // Called every time the user pick
(
CString s, int l ,
// LIST 0W QUEUES From Routing table and what is in Shared Memory
// CListBox* lb = (CListBox*) GetDlglte ( IDCJQUE) , // lb->InsertStrmg(-l, "Ql") , // lb->InsertStrmg(-l, "Q2") , // lb >SetCurSel (0) ,
CComboBox * CB1 = (CComboBox *) this- >GetDlgItem ( IDC_QL) , CBl->ResetContent 0 ,
// List all logical queues from the Routing Table // APPS [physical] , logicall, logιcal2, [physical] , logical, if (smjpase = AttachSharedMemory 0 ) { IpRT rt = RTROOT, while (rt = NextRT (rt)) ( char *e,*s = RT_APPS(rt), // Starts after the first letter while (s = strchr (s, ', ') ) { // Ends at next "," if (e = strchr(++s, ' , ' ) ) ( e = 0, if ( ( 'strchr(s, ' [' ) ) &Sc s) {
CBl->AddStrmg(s) , // lb->InsertStrmg (-1, s)
} '
// Look at shared memory (physical Q names) for "Q"s for ( ι=0, l < SHAREDATA (nsbuf ) , ι++ )( IpSMBUF b = SMBUFADDR (l), if ( strcmp (b->name, Sc" QNETD") ScSc strchr (b- >name ,' Q ' ) ) ( // Anything th if (CBl->FmdStrmgExact ( -1 , b->name) == CBJERR) ( // String is not CBl->AddStrmg(b->name) , // lb->InsertStrmg ( -1, s)
else { GetParentFrame 0 ->SetMessageText ("QNETD not runnmgC) please start it "), MessageBoxf "QNETD not running, please start it " , 0 , MB_ICONSTOP) , //AfxGetMamWndO ->DestroyWmdow 0 ,
CBl->AddStrmg( " ") ,
// CBl->SetCurSel (g_que [QN] ) ; CB1 - >SelectStrιng ( - 1 , g_que [QN] ) ;
void CQmanView: : OnlnitialUpdate ( )
(
LOGFONT If;
CString s,
CFormView: : OnlnitialUpdate () ,- // Default from vc++
// Set frame size = Form size GetParentFrame ( ) - >RecalcLayout ( ) ; ResizeParentToFit (FALSE) ; ResizeParentToFit (TRUE) ;
GetMeterBoxes () ,
DrawKey ( ) ; for (mt ι=0,-ι<3,ι++){
// gjtrackd] = GetDlgltem ( IDCJTRACKS [l] )- >m_hWnd; g_tmιn[ι] = GetDlgltem ( IDCJTMINS [l] ) ->m_hWnd, g_tmax[ι] = GetDlgltem ( IDCJTMAXS [l] ) ->m_hWnd, g_tlab[ι] = GetDlgltem ( IDCJTLABS [ι] )- >m_hWnd, g_pιc[ι] = QNONE, // man g_pιc[ι+3] = QSTOP; // yellow
// Add selections in the list of quenames (needed now, so the CmdLme args wi LoadList ( 0 , IDC_QUES1 ) LoadLlst ( 1 , IDC_QUES2 ) LoadList ( 2 , IDC JQUES3 )
DWORD id;
CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) Poll, (LPVOID) 0,0,Sdd);
CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) Poll, (LPVOID) l,0,&ιd),
CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) Poll, (LPVOID) 2,0, ad);
CmdLme (1) ,
SetTιmer(MYTIMER, 250, NULL) ,- // 1/4 second SetTimei (TITLETIMER, 100 , NULL) ;
// Fonts memset (Self, 0, sizeof (LOGFONT) ) ,- ttifdef BIGFONT
If. If Height = 18; ttelse lf.lfHeight = 13, ttendif g_text_font . CreateFontlndirect (Slf) ; strcpy (If . IfFaceName, "Matura MT Script Capitals") strcpy (If . IfFaceName, "Monotype Corsiva") ; lf.lfHeight = 32; m title font . CreateFontlndirect (&lf) ,-
GetDlgltem (IDCJTITLE) ->SetFont (Scm_tιtle_font) ;
1 = 0; while (ALL_TEXT[ι] )
GetDlgltem (ALLJTEXT [ι++] ) ->SetFont (Scg_text_font )
void CQmanView- : OnHScroll (UINT nSBCode, UINT nPos, CScrollBar^ pScrollBar)
// TODO Add your message handler code here and/or call default // CFormView- : OnHScroll (nSBCode, nPos , pScrollBar), // Removed by derek
void CQmanView. :OpenQue (mt l, int IDC QUES)
(
CString s , que ; mt stat ;
GetDlgltemText ( IDC_QUES , que . GetBuffer (100) , 100) , que .ReleaseBuffer () ,- if (que != g_que[ι]) ( // the user changed the open que name GetParentFrame ( ) - >SetWmdowText ( "QMAN" ) ; if (que == "") { g_pιc [l] = QNONE; g_que [l] = " " ; s = "No Que will be used" ,- Qclose (ScQS [l] ,0) ,- } else { g_pιc[ι] = QSTOP; s . Format ( "Opening que %s",que); memset Ug_s [l] , 0, sizeof (QADMSTATS) ) ; // clear g_startmg [i] = 500; // Aprox 50 seconds
GetParentFrame 0 ->SetMessageText (s) ; // MessageBox (s) , causes 2nd pass if (QS[ι] = Qopen (que. GetBuffer(0) , PUT_MODE, 0 , Q_FAILOVER, ScStat , 0,0) ) ( g_que [l] = que, s .Format ("Qopen (%s) " ,que) ; // QS [l] ->tιme__out = 1000; // 1 second
} else ( s Format ("Qopen (%s) Error %d" , que , stat ) ,- g_pιc [l] = QDOWN,
CComboBox ♦ CB = (CComboBox ) thιs->GetDlgItem ( IDCJQUES) ; CB->SelectStrmg(-l, "") ; g_que[ι] = "",
00027 R GetParentFrame ( ) >SetMessageText (s)
void CQmanView OnSetfocusQuesl 0 ( LoadList (0 , IDC_QUES1) void CQmanView OnSetfocusQues20 j LoadList ( 1 , IDC_QUES2 ) void CQmanView OnSetfocusQues3 { LoadList (2 , IDC QUES3) void CQmanView OnSelchangeQuesl ( ) OpenQue ( 0 , IDC_QUES1 ) , } void CQmanView OnSelchangeQues2 () OpenQue ( 1 , IDC_QUES2 ) , ' void CQmanView OnSelchangeQues30 OpenQue (2, IDC QUES3) , void CallAdm nt id) { if (QS d]) {
CAdminDlg adm adm m_ιd = id adm DoModal ( ) ,
void CallDatadnt id) { f (QSdd]) {
CKeySearch d, // CdataDlg d m_ιd = id, d DoModal ( ) ,
void CQmanView OnAdminbl 0 ( CallAdm(O) void CQmanView OnAdmmb20 j CallAdm(l) void CQmanView OnAdminb30 { CallAdm(2)
void CQmanView OnDatablO ( CallData(O), void CQmanView OnDatab2() j CallData(l), void CQmanView OnDatab3() ( CallData(2), void CQmanView OnDra tCDC* pDC)
(
DrawMeter (0) , DrawMeter (1) , DrawMeter (2) , DrawKey ( ) ,
CFormView OnDraw(pDC),
// this ->SetWmdowText ("Qman av"),
// GetParentFrame 0 ->SetW dowText ("QQMAN"
void CQmanView OnRButtonDown (UINT nFlags, CPoint point)
{
GetParentFrame ( ) >SetMessageText ( " " ) , thιs->Invalιdate ,
CFormView OnRButtonDown (nFlags, point),
00027' // oentrvw cpp implementation of the COentryView class // /*
* *
* + Copyright (C) 1995 MITSUBISHI ELECTRIC ITA ALL RIGHTS RESERVED ** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT ** LAWS OF THE UNITED STATES USE OF A COPYRIGHT NOTICE ** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION ** OR DISCLOSURE **
* * THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE SECRETS OF MITSUBISHI ELECTRIC ITA USE, DISCLOSURE,
* * OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* * EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA
OpenMQ Demo
Module oenrvw cpp
* * Author Derek Schwenke 10/8/95
* *
*/ ttinclude "stdafx h" ttinclude "oentry h" ttinclude "oentrdoc h" ttinclude "dbdlg h" ttinclude "odlg h" ttinclude "oentrvw h" ttinclude 'orderfm h" ttinclude "oraomq h"
//+++++++++++++ QLIB +++++++++++++++++++ ttinclude "glib h" ttinclude " rt h" extern IpSMBUFH smjbase, lpQHANDLE Q,Qrep,
//+++++++++++++ QLIB +++++++++++++++++++ ttdefine REPLY_SUBMODE 1 ttdefine NOMSGQ_SUBMODE 2 ttdefine DIRECT_FILL_TIME_OVER 121 ttdefine PLACEJDRDERJTOQ 0 ttdefine PLACEJDRDER 1 ttdefine FILLJDRDER 2 ttdefine FILL_FROM_ORACLE 3 ttdefine DB_DONFJTIMER 201 ttdefine WAIT_ANAMATE_TIMER 202 ttdefine DIRECTJFILLJTIMER 203 ttdefine FILLJDELAYJTIMER 204 ttdefine FILL_ANAMATE_TIMER 205 ttdefine SET_1ST_TITLE_TIMER 206 ttdefine OPTIONSJ30NEJTIMER 207 ttdefine POLLJFI LJTIMER 208 ttdefine PLACE TIMER 209
ttdef me NEXTB IT ( X ) ( 1 & ( X = X / 2 ) ) tti fde f JDEBUG ttundef THI SJFILE static char BASED_CODE THISJFILE [ ] = FILE ,- ttendif
///////////////////////////////////////////////////////////////////////////// // COentryView
IMPLEMENTJDYNCREATE (COentryView, CFormView)
BEGIN_MESSAGE_MAP (COentryView, CFormView)
// { (AFXJMSGJMAP (COentryView)
ON_BN_CLICKED ( IDC_EXITB , OnExitb)
ON_BN_CLICKED(IDC_ORDERB, OnOrderb)
ONJBN_CLICKED(IDC_AUTOB, OnAutob)
ON_WM_CTLCOLOR ( )
ON_BN_CLICKED(IDC_PLACER, OnPlacer)
ON_BN_CLICKED ( IDC_FILLR , OnFi11r)
ON_CBN_SELCHANGE (IDC_QUE, OnSelchangeQue) ON_MESSAGE(MESSAGEREADY,OnReplyMsg)
ON_BN_CLICKED ( IDC_SENDREPC, OnSendrepc)
ON_BN_CLICKED ( IDCJTRANB , OnTranb)
ON_BN_CLICKED ( IDC_COMMITB , OnCommitb)
ON_BN_CLICKED(IDC_ABORTB, OnAbortb)
ON_WMJLBUTTONDOWN ( )
ON_WM_TIME ( )
ON_BN_CLICKED ( IDC_SHOWDB , OnShowdb)
ON_BN_CLICKED(IDC_FILLDB, OnFilldb)
ON_BN_CLICKED ( IDCJPLACENOQR, OnPlacenoqr)
ON_CBN_EDITUPDATE ( IDC_QUE , OnEditupdateQue )
ON_BN_CLICKED(IDC_OPTIONSB, OnOptionsb)
ON WMJRBUTTONDOWN ( )
//"}AFXJMSGJMAP
// Standard printing commands
ON_COMMAND(IDJFILEJPRINT, CFormView: : OnFilePrmt )
ON_COMMAND(IDJFILEJPRINTJPREVIEW, CFormView: : OnFilePrmtPreview, END_MESSAGEJMAP ( ) i IiIi CiOieiniitriymVieiw m coinmstiruicmt iomn/dieisiitriu nctnio iniii/iiiim iii/mm m m i mi
COentryView : : COentryView 0
CFormView ( COentryView : IDD )
/ / ( (AFXJDATA JI IT ( COentryView) mJDrderMode = 1 ; m_inst = _T { " " ) ; m_sendreply = 0 ;
//} }AFX_DATA_INIT
// TODO: add construction code here m_runflag = 0; m_mes_sent = 0 ,- m_mes_rec = 0; m_rec_sent = 0 ,- m_rec_rec = 0 ; m_color = RGB (0 , 255 , 0) ; m_box_color = m_color; m_que = " " , m_order_num = 0, m_tran_state = 0, m auto tran = 0 ,-
CStrmg g_cust[] = "Jones" , "James" , "Johnson" , "Jacobs" , ' Jaffe" , "Jackson"} ;
CStrmg g __ιtem[] = "Bolts" , "Buckets" , "Buttons" , "Belts" , "Bobbins" , "Boats" } ; mt g_pnce[] = ( 1 ,2 , 3 , 4 , 5 , 6 } ,- mt g_qty[] = (lOOO, 1000,1000, 1000,1000, 1000} ,- mt g_purchases [] = (0,0,0,0,0,0},- mt g_num_purchases [] = {0,0,0,0,0,0},- mt g_total_sales = 0; mt g_db_run = 0 , int g_op ιons_run 0, // mt g_delay = 0 ; mt g_dιrectplace = 0 ,- // Client mt g_waιt_anamate = 0 // Server mt g_dιrect_f ill = 0, // Server mt g_f ιll_anarnate = 0 // Server mt g_fιllmg = 0, // Server mt g_place_tpm = 60, mt g_place_delay = 1000; mt g_fιll_delay = 0, mt g_poll_pps = 10, mt g_poll_delay = 100, mt g_clear_stats = 0, mt g_ora_state = 0, mt g__max__orders = 0 ; char g_oracle_con_str [80] = "scott/tιger@t :grampa :orcl" ;
COLORREF g_new_color, CFont g_tιtle_font , CFont g_text_font, mt WAITS [] = ( IDCJWAITO , IDCJWAIT1 } ; mt FILLS [] = (IDC_FILL0, IDCJFILL1, IDC_FILL2} ; mt ALL_TEXT[] = ( IDC_M0DEB0X, IDC_PLACER,IDC_PLACENOQR,IDC_FILLR,IDC_FILLDB
IDC_0PTI0NSB , IDC_0RDERB0X, IDC_FILLTXT, IDC_SENDREPC, IDCJORDERB , IDC_AUT0B , IDC_
IDC_QUE , IDCJCUST , IDCJITEM , IDC_QTY ,
IDC_QUELAB, IDCJCUSTLAB, IDC_ITEMLAB, IDC_QTYLAB,
IDCJTRANBOX, IDC_TRANB, IDCJCOMMITB, IDC_ABORTB, IDCJEXITB,
IDC_STATBOX, IDCJRECIPTSJLAB, IDCJRECIPTS, IDCJRECIPT, IDC_MSGSJLAB, IDCJMSGS, 0} ,
lpQHANDLE gJLQ; // Listener que global for close OnExit
COentryView: "COentryView ()
void COentryView: : DoDataExchange (CDataExchange^ pDX)
{
CFormView. : DoDataExchange (pDX) ; // ( ( AFX JD AT A_MAP ( COentryView)
DDXJRadio (oDX , IDC_PLACER , mJDrderMode ) ; // DDXJText (pDX , IDC_INST , m_mst ) ;
DDX Check (pDX, IDC_SENDREPC, m_sendreply) ;
//JJAFX DATA MAP } i IIiiCnOeinitiriyiViiieiwiipirii in itiiinmg iiiimiiiiiiiimiiiiiiiiiiiiiiiiiiiiiii illinium
BOOL COentryView: : OnPreparePrint g (CPrintlnfo* plnfo)
(
// default preparation return DoPreparePrmting (plnfo) ; } void COentrvView: :OnBegιnPrιntιng(CDC* /*pDC* / , CPrmtlnfo* l *vlnfo* / )
(
// TODO: add extra initialization before printing
} void COentryView: :OnEndPrmtιng (CDC+ /pDCV, CPrmtlnfo* /♦olnfo^/)
(
// TODO: add cleanup after printing
} void COentrvView : : OnPrmt ( CDCλ pDC , CPrmtlnfo* )
{
// TODO: add code to print the controls
}
//////////////////////////////////////////////////////////////// II I I IIII IIIII II COentryView diagnostics ttifdef JDEBUG void COentryView: : AssertValid () const
{
CFormView: : AssertValid ( ) ;
} void COentryView: : Dump (CDumpContext& dc) const CFormView: :Dump(dc) ;
COentryDoc* COentryView: :GetDocument // non-debug version is inline
ASSERT (m_pDocument->IsKindOf (RUNTIMEjCLASS(COentryDoc) ) ) ; return (COentryDoc4 ) m_pDocument ;
\ ttendif //JDEBUG iiiiiiiiiiiiiiiiiiiiiiiiiiiiimii ii i minimum ii i
II COentryView message handlers void COentryView: :OnExitb ( )
{
CString S; if (g_LQ) Qclose (ϋg_LQ, 0) ; i f ot runnn ng
Figure imgf000284_0001
AfxGetMamWnd ( ) - >DestroyWmdow ( )
//GetParentFrame 0 ->SetMessageTex ( "Unknown message") ; long COentryView: : OnReplyMsg (WPARAM wParam, LPARAM IParam) { CString s,ss; switch (wParam) ( case REPLY_SUBMODE if (IParam)
SetDlgltemText (IDCJRECIPT, (char ♦) IParam) ; else SetDlgltemTex (IDCJRECIPT, "OnReplyMsg Unknown REPLY_SUBMODE Message"
SetDlgltemlnt ( IDC_RECIPTS , ++m_rec_rec) ; break; case NOMSGQ_SUBMODE if (IParam)
MessageBox("NOMSGQ_SUBMODE How did I get here?"),
/*
SetDlgltemln (IDC_MSGS, ++m_mes_rec) , if (g_delay) (
SetTimer (FILLJDELAYJTIMER, g_delay , NULL) , // α_dιrect_f
SetTimer (FILL_ANAMATE_TIMER, 100, NULL) ,
} else g_dιrect_fill = 0; mt nstock = DbOrder (( (pOFORM) IParam) ->cust , ( (pOFORM) IParam) ->ιterr if (instock == 1) ss = "FILLED", else if (instock == 0) ss = "OUT OF STOCK"; else if (instock == -1) ss = "WRONG CUSTOMER", else if (instock == -2) ss = "WRONG ITEM" ;
ε. Format ("Direct • %s: %s %s %d" , LPCTSTR (ss) ,( (pOFORM) IParam) ->cust , ( SetDlgltemText ( IDC_FILLTXT, LPCTSTR (s) ) ,- color the_box( ( (pOFORM) IParam) ->color, 0) ,-
*/ break; case DIRECT_FILL_TIME_OVER:
GetParentFrame ( ) - >SetMessageText (IParam) ,-
// SetDlgltemln (IDC_MSGS, - -m_mes_sent) ; break, default if (IParam) s Format ("ORM %d %s ", wParam, IParam) else s Format ( "Unknown Message ORM"), GetParentFrame ( ) ->SetMessageText (s) ,
} return (0) ,
////////////////////////////////////////////////////////////////////// III II II 111 llll LISTENER THREAD 11 III I III 11111 III III 1111 III mimmiiimimiimimmiiiimmmiiimimimiiiiiiimi typedef struct tpara ( // Thread parameters
HWND αwnd , int onum, // smouff num to send replys to
CString inst } TPARAM, pTPARAM,
TPARAM tp 1/ < - - Global Data so it does not go away
char g_thα_data[l000] , 111111111111171111111
MSGH g_thd_mh, // Listener thread //
DWORD Listen (pTPARAM tp) ( ///////////////////// mt max_dly,md, stat=0,
CString s,n = tp->mst,
if ( gJLQ = Qopen (n GetBuffer (0) ,GETJM0DE, 0, 0 , tsta , 0 , 0) ) { // Save the buffer I will listen to tp->bnum = g_LQ->bufs_found [0] , // Replys will be sent to this buffer if (SHAREDATA (diag) ) { s Format ("Thread Open (%s) bnum=%d" , LPCTSTR (n) , tp->bnum) ,
PostMessaget tp->hwnd,MESSAGEREADY, 0 , (LPARAM) LPCTSTR(s) ),
/♦ // REPLY_SUBMODE (pass sub node as ORM_MES_REC while (QSUCCESS == Qget (gJLQ, &g_thd_mh, data, 1000 ) ) (
PostMessage (tp->hwnd, MESSAGEREADY, g_thd_mh sub_mode . (LPARAM) data), // PostMessage (tp->hwnd, MESSAGEREADY, ORM_MESJRECEIVED, (LPARAM) data),
*/
while (QSUCCESS == QlistenBeforeReply (gJLQ, &g_thd_mh, g_thd_data, 1000) ) { // Got a message could be Recipt or direct fill request if (g_thd_mh sub_mode == REPLY_SUBMODE) (
PostMessage (tp->hwnd, MESSAGEREADY, g_thd_mh sub_mode , (LPARAM)
} else ( g_dιrect_fill = 1, max_dly = 500; // 25 Seconds max check 20 times a second while ( (g_direct_fill || g_filling) && (--max_dly)) Sleep(50); // if (max_dly > 0) md = ACK_M0DE; else { md = NACK_M0DE; g_direct_fill = 0 ,-
MessageBox (NULL, "SER TIME OVER", NULL, ULL) ; s. Format ("%s: SERVER did not reply to DIRECT FILL",n); :: PostMessage (tp->hwnd, MESSAGEREADY, DIRECTJFILLJTIMEJDVER , (LPARA
} } QreplyAfterListen (g LQ,md,0,g thd data,g thd mh.size,0);
}.
} else { s .Format ("Cant Qopen(%s) ERROR=%d" , PCTSTR (n) ,-stat ) ;
MessageBox (tp->hwnd, s, "Listener Thread", MB ICONSTOP) ; }
Qclose UgJLQ, 0) ; return (0) ,-
void COentryView: :CmdLine (int pass) ( CString parm, value, line, nline ,- int i,r,g,b; line = AfxGetApp ( ) ->m_lpCmdLine; while (2 <= (i = sscanf (LPCTSTR (line) , "%s %s % [ @] " , parm.GetBuffer (100) , value .GetBuffer (100) , nline . GetBuffer ( 100 ) ) ) ) parm . MakeUpper ( ) ;
// oentry Name xxx Que ssss RGB r,g,b OrderMode m Fill x Poll x Order x if (pass == 1) { if (parm 'NAME") |m_inst = LPCTSTR (value ) ;} if (parm 'RGB") (sscanf (LPCTSTR (value) , "%d, %d, %d" , &r, &g, Scb) ;m_colo if (parm ORDERMODE") (sscanf (LPCTSTR (value) , "%d" , ScmJOrderMode) ;m_0r if (mjOrderMode < 0 | | m_OrderMode > 3) mJOrderMod if (parm 'FILL") [sscanf (LPCTSTR (value) , %d",ϋg_fill_delay) ;} if (parm 'POLL") [sscanf (LPCTSTR (value) , %d" , &g_poll_pps) ; if((MIN_POLL <= g_poll pps) &δc (g_poll_pps <= MAX_ g_poll_delay = 1000 /g_poll_pps; } if (parm ORDER": (sscanf (LPCTSTR (value) , "%d" , &g_place_tpm) ; if((MIN_AUTO <= g_place __tpm) && (g_place_tpm <= MA g_place_delay = 6000 0/g_place_tpm; } if (parm "ORACLE") strcpy (g_oracle_con str , LPCTSTR (value) ) ; }
} else ( if (parm == "QUE" || parm == "SERVER") {
CComboBox ♦ CB = (CComboBox ) this- >GetDlgItem ( IDC_QUE) ; CB->SelectString (-1, value) ; OnSelchangeQue 0 ;
line = LPCTSTR (nline) nline = " " ;
void COentryView : :LoadQList (int mode)
{
// mode=0 : List Non-Ques // mode=l : List Ques int i ;
CComboBox ^ 06 = (CComboBox ) this- >GetDlgItem ( IDC_QUE) ,- CB->ResetContent () ;
// List all logical queues
// APPS: [physical] , logicall, logical2, [physical] , logical, if (smjbase = AttachSharedMemory ()) { IpRT rt = RTROOT; while (rt = NextRT (rt)) ( char e^s = RT_APPS(rt); // Starts after the first letter while (s = strchr (s, ',') ) { // Ends at next "," if (e = strchr (++s, ',') ) { e = 0; if ( ( Istrchr (s, ' [ ' ) ) && ♦s) ( if ((mode && strchr (s, 'Q' ) ) || ( ! mode && ! strchr (s, ' Q ') ) CB->AddString(s) ; // lb- >InsertString ( -1 , s)
// Now add any extra entries from the local node that were not in the RT // IpSMBUF BUF; for (i = 0; i < SHAREDATA (nsbuf) ; i++) { if (! strcmp ( (SMBUFADDR (i) ) ->name, "empty" ) ) continue; if (! strcmp ( (SMBUFADDR (i) ) ->name, "QNETD" ) ) continue; if (CBJERR != CB->FindStringExact (-1, (SMBUFADDR (i) ) ->name) ) continue; / if ((mode && strchr ( (SMBUFADDR (i) ) ->name, ' Q' ) ) || (Imode && !strchr((SM CB->AddString( (SMBUFADDR (i) ) ->name) ; // lb- >InsertString ( -1 , s)
} else {
MessageBox ( "QNETD not running. Please restart.");
} CB->AddString("") ; if ( CBJERR == (i = CB->FindStringExact (-l,m_que) ) )
CB->SetCurSel (0) ,- else
CB->SetCurSel (i) ;
OnSelchangeQue ( ) ,- void COentryView OnlnitialUpdate ( )
CString s,
CFormView OnlnitialUpdate () ,
// Set frame size = Form size GetParentFrame ( ) - >RecalcLayout ( ) , ResizeParentToFit (FALSE) , ResizeParentToFit (TRUE) mJDrderMode = PLACEJDRDER,
LoadQList (1)
CmdLme (1) ,
// Set max size on data fields
( (CEdit ) thιs->GetDlgItem(IDC_CUST) ) - >LιmιtText ( 9 ) ,
( (CEdit ) thιs->GetDlgItem(IDC_ITEM) ) - >LιmιtText ( 9 ) ,
( (CEdit ) thιs->GetDlgItem(IDC_QTY) ) - >LιmιtText ( 9) ,
// Generate unique instance name on this node if (m_mst == "") // May be set by command line "name" m_mst Format ( "OE%d" , SHAREDATA (ap app_num)++),
OnAnyUserAction ( ) ,
SetTimer ( SET_1ST_TITLE_TIMER , 100 , NULL) , // Calls OnAnyUserAct ion ( ) , to set t
// Start the backgound thread to Qget ( ) messages
DWORD id , tp hwnd = m_hWnd , tp mst = m_ιnst ,
CreateThread (NULL , 0 , ( LPTHREAD_START_ROUTINE ) Listen , ( LPVOID) &tp , 0 , &ιd)
CmdLme ( 2 ) ,
( (CButton ) thιs->GetDlgItem(IDC_PLACER) ) - >SetCheck ( 0 )
( (CButton ) thιs->GetDlgItem(IDC_PLACENOQR) ) - >SetCheck ( 0 )
( (CButton ) thιs->GetDlgItem(IDC_FILLR) ) - >SetCheck ( 0) ,
( (CButton *) thιs->GetDlgItem(IDC_FILLDB) ) - >SetCheck ( 0) , if ( JDrderMode == PLACEJDRDER)
( (CButton ) thιs->GetDlgItem(IDC_PLACER) ) - >SetCheck (1) , if (mJDrderMode == PLACEJDRDERJNJOQ)
( (CButton ) thιs->GetDlgItem(IDC_PLACENOQR) ) ->SetCheck (1) , if (mJDrderMode == FILLJDRDER)
( (CButton ♦) thιs->GetDlgItem(IDC_FILLR) ) - >SetCheck ( 1) , if (mJDrderMode == FILL_FROM_ORACLE)
( (CButton ♦) thιs->GetDlgItem(IDC_FILLDB) ) ->SetCheck (1) ; ttifdef ORACLE
((CButton ♦) thιs->GetDlgItem(IDC_FILLDB) ) ->EnableWmdow (TRUE) , ttelse
( (CButton ) this->GetDlgItem(IDC_FILLDB) ) - >EnableWindow (FALSE) ; ttendif
PlaceOrFillMode (m_OrderMode) ;
// Fonts
LOGFONT If; memset (&lf , 0, sizeof (LOGFONT) ) ; ttifdef BIGFONT lf.lfHeight = 18; ttelse lf.lfHeight = 13; ttendif g_text_font . CreateFontlndirect (&lf ) ,- strcpy (If . IfFaceName, "Monotype Corsiva") ; lf.lfHeight = 32; g_title_font . CreateFontlndirect (Slf) ,-
GetDlgltem (IDC_BIG_TITLE) - >SetFont ( &g_title_font ) ,- int i = 0 ; while (ALL_TEXT[i] )
GetDlgltem (ALLJTEXT [i++] ) ->SetFont (&g_text_font ) ;
//void COentryView: : OnEditchangeQue ( ) void COentryView: : OnEditupdateQue ( )
OnSelchangeQue () ;
void COentryView: : OnSelchangeQue ( )
CString que, s ; int stat=0;
// Get the que name
GetDlgltemText (IDC_QUE, que .GetBuffer (100) , 100) ,- que. ReleaseBuffer ;
if (que != m_que) { // New value if (Q) Qclose (&Q,0) ; if (que == "") { // No que m_que = " " ,- s = "No Que will be used" ;
GetDlgltem (IDC_AUTOB) ->EnableWindow (FALSE) ; GetDlgltem (IDC_ORDERB) ->EnableWindow (FALSE) ;
} else ( // Set value s . Format ( "Opening que %s " , que ) ; GetParentFrame 0 ->SetMessageText (s) ,- if (Q = Qopen (que. GetBuffer (0) , PUT_MODE, 0, 0, ScStat, 0, 0) ) ( if (m_sendreply)
Q->msgh. reply_smbuf = tp.bnum; m_que = que ; s . Format ( "Qopen (%s) " , que) ;
GetDlgltem (IDC_AUTOB) ->EnableWindow (TRUE) ,- GetDlgltem (IDC_ORDERB) - >EnableWindow (TRUE) ; if (mJDrderMode == PLACE_ORDER_NOQ) Q - >msgh . sub_mode = NOMSGQJ3UBMODE ;
} else { s . Format ( "Qopen (%s) Error %d" , que, stat ) ; GetDlgltem (IDC_AUTOB) - >EnableWindow (FALSE) ,- GetDlgltem (IDCJDRDERB) - >EnableWindo (FALSE) ;
GetParentFrame ( ) - >SetMessageText (s) ;
}
OnAnyUserAction ( ) ;
OFORM g_buf ;
DWORD DirectPlaceO ( int flags = 0 ,-
QsendAndReceive (Q, 0 , SUB_MODE_OK, flags , sizeof (gjbuf ), (char ) &g_buf, 0,0, u, g_directplace = 0; return ( 0 ) ,- }
//ORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDER //ORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDER //ORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDER //ORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDER //ORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDER void COentryView: :OnOrderb ()
( // Check m_ordermode = 0 to place order or = 1 to fill the order CString que, str, s = ""; int gsize,stat=0, flags, instock, filled=0; // OFORM buf ,- char line [sizeof (OFORM) +10] ;
MSGH mh; // To get detailed put status
DWORD id; if (g_directplace) return,- // direct place thread is already working if (g_filling) return; // Wait for fill done is already working if (Q) ( if (!m_runflag) OnAnyUserAction 0 ; if (m_auto_tran) { if (m_auto_rand < 16) m_auto_rand = rand ( ) ;
// Begin a tran? if ( (m_auto_tran == 1 ) ScSc NEXTBIT (m_auto_rand) ) { if ( ! m_tran_state ) m_tran_state= 1 ; // Done by OnTran ( causes m_autoJtran = 2 ,- GetDlgltem ( IDC_TRANB ) - >ShowWindow ( SW_HIDE) ,- if (m_auto_commit = NEXTBIT (m_auto_rand) )
GetDlgltem (IDC_COMMITB) - >ShowWindow (SW_SHOW) ; else
GetDlgltem (IDC_ABORTB) ->ShowWindow (SW SHOW) ;
// Set the flags for get or put if (m_tran_state) if (m_tran_state++ == 1) flags = QJTRANJBEGIN; else flags = QJTRAN; else flags = 0 ;
if (mJDrderMode <= PLACEJDRDER) ( // Place the order
// Read the data to be sent
GetDlgltemText ( IDC_CUST, g_buf . cust , 10) ;
GetDlgltemText (IDC_ITEM, gjouf . item, 10) ,- gjouf.qty = GetDlgltemlnt ( IDC_QTY, ULL, TRUE) ; gjbuf . color = m_color; g_buf . reply_to = SHAREDATA (hostip) ;
SetDlgltemlnt (IDC_MSGS, ++m_mes_sent ) ; if (mJDrderMode == PLACE_ORDER_NOQ) ( g_directplace = 1 ,-
GetDlgltem (IDCJDRDERB) ->EnableWindow (FALSE) ;
SetTimer (WAIT_ANAMATE_TIMER, 400, NULL) ,-
CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) DirectPlace, (LPVOID) 0
} else if (QSUCCESS == (stat = QsendAndReceive (Q, 0 , SUB_MODE_OK, flags, s if (mh.mode == ACK_MODE ScSc mh.sub_mode == SUB_MODE_OK) { m_tran_sent++ ,- s . Format ( "%s : %8s %8s %d" , m_que .GetBuffer (0) , gjbuf . cust , gjbuf . ite } else ( if (mh.sub_mode == SUB_MODE_FULL) if (m_runflag) s. Format ("que is FULL"); else
MessageBox ( "que is FULL"); else s. Format ("Qput () error %d" ,mh. sub_mode) ;
} else { // not QSUCCESS (communications error) SetDlgltemlnt (IDC_MSGS, - -m_mes_sent ) ; s. Format ("Communication error code %d",stat);
} GetParentFrame () - >SetMessageText (s) ;
} else ( // FILLJORDER Fill the order ♦gjbuf. cust = ♦gjbuf. item = 0 ; g_buf . qty = 0 ; if (g_direct_fill) ( // There was a direct placed order to fill pOFORM po = (pOFORM) Scg_thd_data ,- CString ss;
SetDlgltemlnt (IDC_MSGS, ++m_mes_rec) ; if (g_fill_delay) ( g_filling = 1; // Do not fill another until the timer expires SetTimer (DIRECTJFILLJTIMER, g_fill_delay, NULL) ,- // g_di
SetTimer(FILL ANAMATE TIMER, 100 , NULL) ;
} color_the_bo ( po->color , 0) ; int instock = DbOrder (po- >cust , po->item, po->qty); if (instock == 1) ss = "FILLED"; else if (instock == 0) ss = "OUT OF STOCK"; else if (instock == -1) ss = "WRONG CUSTOMER"; else if (instock == -2) ss = "WRONG ITEM"; filled++ ; s. Format ("Direct : %s: %s %s %d" , LPCTSTR (ss) , po->cust, po->item, po- SetDlgltemText (IDC_FILLTXT, PCTSTR (s) ) ;
g_direct_fill = 0 ,- if (g_filling) return;
if (QSUCCESS == (stat = QsendAndReceive (Q, REQUESTJMODE , SUB_MODE DK, flag sizeof (gjouf) , (char ) Scg_buf , Scgsize, Scmh) ) ) { if (mh.mode == ACK_MODE &Sc mh . sub_mode == SUB_MODE_OK) ( SetDlgltemlnt (IDC_MSGS, ++m_mes_rec) ,- if (gsize < sizeof (OFORM) ) s. Format ("Bad reply length"); else ( // you got valid message m_tran_rec++; colorjthejbox (gjbuf .color, 0) ; // But dont force it if (mJDrderMode == FILLJFROMJDRACLE) instock = OraOrder (g_buf . cust , gjbuf . item, gjbuf -qty) ,- // Ora else instock = DbOrder (g_buf .cust, gjbuf . item, g_buf .qty) ; if (g_fill_delay) ( g_filling = 1; // Do not fill another until the timer expir
SetTimer (FILLJDELAYJTIMER, g_fill_delay, NULL) ; /
SetTimer (FILL ANAMATE TIMER, 100 , NULL) ;
} else if (mh.sub_mode == SUB_MODE_EMPTY) {
000^90 if (m_runflag | | filled) s . Format ( "Que Empty"); else
MessageBox ( "Que Empty"); } else s . Format ( "Bad reply mode %d : %d" , mh. mode , mh . sub_mode) ;
} else ( // not QSUCCESS (communications error) mh.mode = 0;// Not ACKJMODE s . Format ( "Communication Error Code %d",stat); } if (gsize == sizeof (OFORM) ) ( if (instock == 1 ) sprintf (line, "FILLED :%9s %9s %d" , gjbuf . cust,g_buf . item,σjnuf .qty) else if ( instock == 0) sprintf (line, "OUT OF STOCK:%9s %9s %d" , g_bu . cust , gjbuf . item, g_bu else if ( instock == -1) sprintf (line, "NO SUCH ITEM:%9s %9s %d" , g_buf . cust , g_buf . item, g_bu else // instock == -2 sprintf (line, "NO SUCH CUSTOMER:%9s %9s %d" , g_buf . cust , g_buf . item, SetDlgltemText ( IDCJFILLTXT, line) ;
}
// else
// strcpy (line, "") ,-
// Send Reply if requested if ( (mh. reply_smbuf >= 0 ) ScSc (mh. reply_smbuf < SHAREDATA (nsbuf) ) &Sc 's mh. mid. host = g__buf . reply_to; // HACK! Makes sure sending host ge
Qrep = QopenReply (Qrep, Scmh, 0, 0, 0) ;
if (QSUCCESS != (stat = Qput (Qrep, 0 , REPLY_SUBMODE, 0 , sizeof ( line) , lin ε . Format ( "Qput (%s) Error %d" , Qrep->msgh . to_server , stat ) ; else s . Format ( "Replying Qput(%s) to smbuf %d" , Qrep- >msgh . to_server , Qre
SetDlgltemlnt ( IDCJRECIPTS , ++m_rec_sent ) ;
}
GetParentFrame 0 ->SetMessageText (s) ,- /* if (m_runflag mh.mode == ACK_MODE) // We got something
OnOrderb ( ) ,- // Check again for next message, no need to wait, 'else // We didnt get anything color_the_box ( m_color,0); // restore old color
*/ if ( ! m_runf lag &Sc ! g_f ill_delay) colorjthejbox ( πjcolor, 0 ) ;
} // place or fill
if ( (mJDrderMode <= PLACEJDRDER) || mh.mode == ACKJMODE) // Placeing or if (m_auto_tran > 1) ( if ( ( NEXTBIT (m_auto_rand) Sc& NEXTBIT (m_auto_rand) ) I I (m auto tran++ > 8) ) ( / / Commit or Abort tran? if (m_auto_commit )
OnCommitb 0 ; else
OnAbortb ( ) ; m auto tran = 1 ;
if ( (mJOrderMode >~ FILL_ORDER) ScSc m_runflag ScSc mh.mode == ACKJMODE ScSc mh.sub_mode == SUB_MODE_OK) if (g_max_orders++ < 200)
OnOrderbO; // Try to get one more item, else g_max_orders = 0 ; } else g_max_orders = 0 ;
// The order or fill button will be active until we are done. // CButton ♦ CB = (CButton ) this- >GetDlgItem ( IDCJDRDERB) ,- // CB->SetState(TRUE) ;
}
//
// m_auto_tran:
// 0 No auto trans
// 1 No tran yet
// 2 After OnAutobO
// int g_poll_delay_old; int g_place_delay_old; void COentryView: :OnTimer (UINT nIDEvent)
{ if (nIDEvent == PLACEJTIMER ) { if (g_directplace) return; // direct place thread is already working if (g_filling) return; // Wait for fill done is already working if (g_place_delay_old != g_place_delay) (
KillTimer (PLACEJTIMER) ;
SetTimer (PLACEJTIMER, g_place_delay_old = g_place_delay, NULL) ;
SetDlgltemText (IDC_CUST,g_cust [m_order_num % 6] ) ,- SetDlgltemText (IDC_ITEM,g_item[m_order_num % 5] ) ,- SetDlgltemlnt (IDC_QTY,1 + (m_order_num++ % 9), FALSE);
OnOrderbO ;
//CButton ^ 06 = (CButton ) this->GetDlgItem (IDC_ORDERB) ;
//CB->SetState(TRUE) ;
} else if (nIDEvent == POLL_FILL_TIMER) { if (!g_filling) ( if (g_poll_delay != g_poll_delay_old) ( KillTimer (POLLJFILLJTIMER) ; SetTime ( POLL_FILL_TIMER , g_poll_delay_old = g_poll_delay , NULL) ;
OnOrderb ( ) ; }
} else if (nIDEvent == WAIT_ANAMATE_TIMER) { if (g_directplace) (
// Anomate the wait 0,1 0,1
GetDlgltem (WAITS [g_wait_anamate++] ) - >ShowWindow (SWJHIDE) ; if (g_wait_anamate > 1) g_wait_anamate = 0 ; GetDlgltem (WAITS [g_wait_anamate] ) ->ShowWindow (SW_SHOW) ; } else (
KillTimer (WAIT_ANAMATE_TIMER) ;
GetDlgltem (IDC_ORDERB) - >EnableWindo (TRUE) ;
GetDlgltem (WAITS [g wait anamate] ) ->ShowWindo (SW HIDE);
}
} else if (nIDEvent == FILL_ANAMATE_TIMER) ( if (g_filling == 0) ( // End Anamation KillTimer (FILL_ANAMATE_TIMER) ; GetDlgltem (FILLS [g_fill_anamate] ) ->ShowWindow (SW_HIDE) ;
} else ( // Anamate 0,1,2
GetDlgltem (FILLS [g_fill_anamate++] ) ->ShowWindow (SWJHIDE) ; if (g_fill_anamate > 2) g_fill_anamate = 0;
GetDlgltem (FILLS [g_fill_anamate] ) ->ShowWindow (SWjSHOW) ; if (1) ( // g_progress
// ( (CButton ) this->GetDlgItem(IDCJPLACER) ) - >SetCheck (0) ; // GetDlgltem (IDCJPROG) ) ->SetRange (0, 100) ; // ((CProgressCtrl ♦) this->GetDlgItem ( IDCJPROG) ) ->SetRange (0 , 100) ,- // ((CProgressCtrl ) this->GetDlgItem (IDC_PROG) ) ->SetPos (50) ; // ((CProgressCtrl ) this- >GetDlgItem ( IDCJPROG) )- >ShowWindo (SW_SHOW
} else if (nIDEvent == DIRECT_FILL_TIMER) { g_direct_fill = 0; // let QsarO return. g_filling = 0; // End Anamation, let next order in KillTimer (DIRECTJFILLJTIMER) ; color_the_bo ( m_color,0); // Restore the old color
} else if (nIDEvent == FILLJDELAYJTIMER) { g_filling = 0; // End Anamation, let next order in KillTimer (FILLJDELAYJTIMER) ; color_the_bo ( m_color,0); // Restore the old color
} else if (nIDEvent == SETJ1ST_TITLE_TIMER) { // Only done once
KillTimer (SETJlSTjriTLEJTIMER) ; OnAnyUserAction () , else if (nIDEvent == DBJDONEJTIMER) { if (g_db_run == 40) { g_db_run = 0 ,
GetDlqItem(IDC_SHOWDB) ->EnableWmdow (TRUE) , KillTimer (DB DONE TIMER),
}
} else if (nIDEvent == OPTIONSJDONEJTIMER) ( if (g_optιons_run == 40) ( // End g_optιons_run = 0,
GetDlgltem ( IDCJDPTIONSB) - >EnableWmdow (TRUE) KillTimer (OPTIONS DONE TIMER),
if (m_color ' = g_new_color) ( color the box(m color = g_new_color, 1)
if (g_clear_stats) { g_ciear_stats = 0, m_mes_sent = 0, m_mes_rec = 0 , m_rec_sent = 0, ra_rec_rec = 0 ,
SetDlgltemlnt (IDC_MSGS, 0), SetDlgltemlnt (IDC RECIPTS, 0),
} else
CFormView OnTimer (nIDEvent ) ,
void COentryView OnAutob ( ) if (m_runflag) {
KillTimer (PLACEJTIMER) ,
KillTimer (POLL_FILL_TIMER) , m_runflag = 0 , 11 You are no longer running if (m_auto_tran) OnAbortb ( ) , m_auto_tran = 0 ,
SetDlgltemText (IDC_AUTOB, "Auto") ,
GetDlgltem (IDC_EXITB) ->EnableWmdow (TRUE) ,
((CButton ♦) this- >GetDlgItem ( IDC_PLACER) ) - >EnableWmdow (TRUE) , ( (CButton ♦) thιs->GetDlgItem(IDCJPLACENOQR) ) - >EnableWιndo (TRUE) ((CButton ♦) thιs->GetDlgItem(IDCJFILLR) ) - >EnableWιndow (TRUE) , ttifdef ORACLE
( (CButton ♦ ) thιs - >GetDlgItem ( IDCJFILLDB ) ) - >EnableWmdow (TRUE) , ttendif color_the_box ( m_color,l), // Restore default color
} else { πjrunflag = 1, // You will be running m_order_num = 0, // 1st order number Controls order selections m auto tran = m tran state, // make random transactions too7
O00Z94 if ( mJDrderMode > PLACEJDRDER ) // FILL
SetTimer ( POLL_FILL_TIMER , g_poll_delay_old = g_poll_delay , NULL) ; else
SetTimer ( PLACEJTIMER, g_place_delay_old = g_p lace_de lay, NULL) ;
SetDlgltemText ( IDC_AUTOB , Stop
GetDlgltern ( IDC_EXITB) - >EnableWmdow (FALSE)
( (CButton *) thιs - >GetDlgI tem ( IDC_PLACER) ) - >EnableWmdow ( FALSE) ; (CButton *) thιs - >GetDlgI tem ( IDCJPLACENOQR) ) - >EnableWιndow ( FALSE)
( (CButton ♦) thιs - >GetDlgItem ( IDC_FILLR) ) - >EnableWmdow ( FALSE) ,- ( (CButton ) thιs - >GetDlgItem ( IDC_FILLDB) ) - >EnableWιndow ( FALSE) ;
OnAnyUserAction ( ;
// Color Color Color Color Color Color Color Color Color Color // Color Color Color Color Color Color Color Color Color Color // Color Color Color Color Color Color Color Color Color Color
void COentryView: :OnColor ()
{
CHOOSECOLOR cc ; // common dialog box structure COLORREF acrCustClr [16] ;
// Setup the custom colors as a grey scale for (int v=0,ι=0; l < 16; v=17 ι++) acrCustClr [l] = RGB(v,v,v);
// Initialize the necessary members. cc.lStructSize = sizeof (CHOOSECOLOR) ,- cc.hwndOwner = NULL; // = hwnd; cc.lpCustColors = (LPDWORD) acrCustClr; CC. Flags = CC_FULLOPEN; // CC_PREVENTFULLOPEN
if (ChooseColor (Sccc) ) { CString s,- m_box_color = m__color = cc . rgbResult ; // lpCustColors Invalidate () ,- // Display the new color } else (
GetParentFrame 0 ->SetMessageText ("Color was not changed");
}
OnAnyUserAction () ;
//Hinit = i;
HBRUSH COentryView: :OnCtlColor(CDC^ pDC, CWnd^ pWnd, UINT nCtlColor)
( if (nCtlColor == CTLCOLOR_EDIT) ( if (pWnd->GetDlgCtrlID() == IDC_COLORBOX) { pDC->SetBkColor (m_color) ; m_orusn = reaceboiiQBrusn ιm_color) return (m brush);
} else if (nCtlColor CTLCOLOR_BTN ) { // CTLCOLOR EDIT if (pWnd->GetDlgCtrlID() = IDC AUTOB) if (m_runflag) { pDC->SetBkColor(RGB(255,0,0) ) ; // SetBkColor SetTextColor pDC->SetTextColor (RGB (255 , 255 , 255) ) ; // SetBkColor SetTextColor mjbrush = CreateSolidBrush (m_color) ,- return (mjbrush) ;
}
// } else if (nCtlColor == CTLCOLOR_STATIC ) // CTLCOLOR EDIT
// if (pWnd->GetDlgCtrlID() == IDC_INST) (
// // pDC->SetBkColor(RGB(255,0,0) ) ; // SetBkColor SetTextColor
// // pDC->SetTextColor (RGB (255 , 255 , 255 ) ) ; // SetBkColor SetTextColor
// // m_brush = CreateSolidBrush (m_color) ,-
// m_brush = CreateSolidBrush (m_box_color) ,- // empty non-text background
// pDC->SetBkColor (mJbox_color) ; // behind the letters
// return (m brush);
// )
HBRUSH hbr = CFormView :: OnCtlColor (pDC, pWnd, nCtlColor); return hbr;
int COentryView: : DbOrder (char cust, char item, int qty) { int custn=0 , itemn=0 ; while (strcmp (item, g_item [itemn] ) ) if (++itemn == 6) return (-1); while (strcmp (cust , g_cust [custn] ) ) if (++custn == 6) return (-2); if (g_qty [itemn] >= qty) { g_qty [itemn] -= qty; g_purchases [custn] += qty g_price [itemn] ; g_num_purchases [custn] ++,- g_total_sales += qty ♦ g_price [itemn] ;
'} else return (0) ; return ( 1 ) ;
int COentryView: :OraOrder(char cust, char item, int qty) { int custn=0, itemn=0, price, stock, re, cust_orders, cust_sales ; CString s; while (strcmp (item, g_item [itemn] ) ) if (++itemn == 6) return(-l); while (strcmp (cust, g_cust [custn] ) ) if (++custn == 6) return (-2);
if (g_ora_state == 0) {
GetParentFrame 0 ->SetMessageText ("Cant Order from oracle: not connected' return ( 0 ) ,- } // Read Oracle if ( (re = orareaddtem, &price, &stock) ) ) { s . Forma ( "OraRead Error %d",rc);
GetParentFrame () ->SetMessageText (s) ; return (0) ;
} if ( (re = oracustr (cust , Sccust_orders , Sccust_sales) ) ) s .Format ("OraCustRead Error %d",rc);
GetParentFrame () ->SetMessageTex (s) ;
if (qty > stock) { return(O); // MessageBo ( "OutOfStock" )
} else ( stock -= qty; g_total_sales += qty price; cust_sales += qty price; cust orders++;
// Write Oracle if ( (re = orawrite (item, stock)) ) { s . Format ( "OraWrite Error %d",rc);
GetParentFrame ( ) ->SetMessageText (s) ,- return (0) ;
} if ( (re = oracust (cus , cust_orders, cust_sales) ) ) s . Format ( "OraCustWrite Error %d",rc); GetParentFrame ( ) ->SetMessageText (s) ,-
return (1) ;
void COentryView: :PlaceOrFillMode (int mode) mJDrderMode = mode; int SHOW, HIDE, IsPlaceMode; if (mode <= PLACEJDRDER) {
HIDE = SW_HIDE;
SHOW = SW_SHOW;
IsPlaceMode = TRUE; } else {
HIDE = SW_SHOW;
SHOW = SWJHIDE;
IsPlaceMode = FALSE; }
GetDlgltem ( IDCjSENDREPC) - >ShowWindow (SHOW) ; // Show sendreply checkbox if (mJDrderMode <= PLACEJDRDER) { 000 ? Q 7 SetDlgltemText (IDCJDRDERB, "Order") , // Order = Order
SetDlgltemText ( IDCJDRDERBOX, "Place Orders"), // Order = Order
SetDlgltemText (IDC_BIG_TITLE, "OpenMQ Place Orders"), // Order
} else (
SetDlgltemText (IDCJDRDERB, "Fill") , SetDlgltemText (IDCJDRDERBOX, "Fill Orders") , SetDlgltemText (IDC BIG TITLE, "OpenMQ Fill Orders"),
} " "
GetDlgltem (IDC_SHOWDB) - >ShowWmdow (HIDE) ,
GetDlgltem (IDC_CUST) - >ShowWιndow (SHOW) , GetDlgltem (IDC_ITEM) - >ShowWmdow (SHOW) , GetDlgltem (IDCJQTY) ->ShowWmdow (SHOW) , GetDlgltem (IDC_CUSTLAB) - >ShowWmdow (SHOW) , GetDlgltem ( IDCJITEMLAB) - >ShowWιndow (SHOW) , GetDlgltem (IDC_QTYLAB) - >ShowWmdow (SHOW) ,
GetDlgltem (IDC_FILLTXT) >ShowWιndow (HIDE) ,
// ( (CEdit ) thιs->GetDlgItem(IDC_CUST) )- >SetReadOnly (FALSE) , // ( (CEdit ) thιs->GetDlgItem(IDC_ITEM) ) ->SetReadOnly (FALSE) , // ( (CEdit ) thιs->GetDlgItem(IDC_QTY) )- >SetReadOnly ( FALSE) ,
// Stats if (mode <= PLACEJDRDER) {
SetDlgltemText ( IDCJMSGSJAB "Sent "), SetDlgltemText ( IDCJRECIPTSJLAB, "Received ") , SetDlgltemlnt (IDCJMSGS, m_mes_sent) , SetDlgltemlnt (IDCJRECIPTS, m_rec_rec) , } else {
SetDlgltemText ( IDC_MSGSJLAB, "Received ") , SetDlgltemText (IDCJRECIPTSJLAB, "Sent ") , SetDlgltemlnt (IDC_MSGS, m_mes_rec) , SetDlgltemlnt (IDC RECIPTS, m rec sent),
} if (mode '= PLACEJDRDER_NOQ) {
GetDlgltem ( IDCJTRANBOX) - >ShowWmdow (SW_SHOW) , if (m_tran_state) {
GetDlgltem ( IDCJDOMMITB) - >ShowWmdow (SW_SHOW) ,
GetDlgltem (IDC_ABORTB) ->ShowWmdow (SW_SHOW) , } else
GetDlgltem (IDCJTRANB) ->ShowWιndow (SW_SHOW) , } else {
GetDlgltem (IDCJTRANBOX) - >ShowWmdow (SWJHIDE) , GetDlgltem (IDCJTRANB) - >ShowWmdow (SWJHIDE) , GetDlgltem ( IDCjCOMMITB) ->ShowWmdow (SWJHIDE) , GetDlgltem (IDC_ABORTB) - >ShowWmdow (SW_HIDE) , GetDlgItem(IDC_SENDREPC) >ShowWmdow (SWJHIDE) ,
if (mode == PLACEJORDER_NOQ) ( LoadQList (0) , // Load non-Que
} else {
LoadQList (1) , // Load Que names // DB if (mode <= PLACEJDRDER) if (g_db_run) g_db_run = 40; // Turn off the DB display if it was left on.
if (mode == FILLJFROMJDRACLE) { if (g_ora_state == 0) if (oraconn (g_oracle_con_str) )
MessageBox ("Oracle Connect Failed"); else g_ora_state = 1; } else ( if (g_ora_state == 1) if (oradisc ( ) )
MessageBox ( "Oracle Disconnect Failed"); else g_ora_state = 0 ,-
OnAnyUserAction ( ) ;
} void COentryView: : OnPlacenoqr ()
{ if ( ! ( ( CButton ♦ ) GetDlgltem ( IDC_PLACENOQR) ) - >GetCheck ( ) return ;
PlaceOrFillMode ( PLACE JDRDER_NOQ) ;
OnAnyUserAction ( ) ;
} void COentryView : :OnPlacer ( )
( if (! ((CButton ♦) GetDlgltem ( IDC_PLACER) )- >GetCheck () ) return;
PlaceOrFillMode (PLACEJDRDER) ;
OnAnyUserAction ( ) ,-
void COentryView: :OnFillr()
{ if (!( (CButton ♦) GetDlgltem ( IDCJFILLR) ) ->GetCheck() ) return;
PlaceOrFillMode (FILLJDRDER) ; OnAnyUserAction ( ) ,-
void COentryView: :OnFilldb()
( if (! ((CButton ♦) GetDlgltem ( IDCJFILLDB) ) ->GetCheck() return;
PlaceOrFillMode ( FIL JFROMJORACLE) ; OnAnyUserAction ( ) ;
void COentryView : : OnAnyUserAction 0 SetDlgltemText (IDC_RECIPT, "") ; SetDlgltemText (IDC_FILLTXT, "") ; if (m_que == "")
GetParentFrame () ->SetWindowText (m_inst + ": No server is selected" ) ; else if (mJDrderMode == PLACEJDRDER)
GetParentFrame () ->SetWindowText (m_inst + ": Place orders into queue " + m else if (mJDrderMode == PLACE_ORDER_NOQ)
GetParentFrame () ->SetWindowTex (m_inst + ": Place orders directly to. " + m else // FILL
GetParentFrame 0 ->SetWindowText (m_inst + ": Fill orders from queue " + m q m box color = m color;
void COentryView: :OnSendrepc ()
( m_sendreply = !m_sendreply; // How can I get this info? if ( Q ) if ( m_sendreply )
Q->msgh. reply_smbuf = tp.bnum; else
Q->msgh. reply smbuf = -1; } void COentryView: : colorJthejbox (COLORREF color, BOOL forceit) { if (( mJbox_color != color ) | | forceit) ( m_box_color = color;
// The DC for the color box CDC+ pCOLORDC = GetDlgltem ( IDCJDOLORBOX) - >GetDC () ; // pCOLORDC- >GetRect 0 ;
// Create a PEN
// CPen ♦pQPen = new CPen (PSJ30LID, 3 , RGB (0 , 0 , 255 ) ) ,-
// CPen ♦pOldPen = pXDC->SelectObject (pQPen) ,-
// Create the Brush
CBrush ♦pQBrush = new CBrush (color) ,-
// Select this brush, save the old
CBrush ♦pOldBrush = pCOLORDC- >SelectObject (pQBrush) ;
// Draw the box
// pCOLORDC- >Rectangle (CRect (1 , 1 , 65 , 65) ) ; pCOLORDC- >Rectangle (m_color_box_rec) ,- pCOLORDC- >SelectObj ect (SpOldBrush) ,- // Reset the brush delete (pQBrush) ; ReleaseDC (pCOLORDC) ;
// GetDlgltem (IDCJLOGOJQ) -invalidate () ; // GetDlgltemdDC INST) - >Invalidate ( ) ;
} } void COentryView : : 0nDraw ( CDC+ pDC ) (
/* pControlDC->SelectStockObject (WHITE BRUSH) ; */
// The DC for the Instance name
/*
CDC^ pINSTDC = GetDlgltem (IDC_INST) ->GetDC() ; pINSTDC->SetBkColor (m_color) ; pINSTDC- >SetTextColor (m_color) ; pINSTDC->SetBkMode (TRANSPARENT) ; pINSTDC- >SelectStockObject (HOLLOW_BRUSH) ; */
GetDlgltem ( IDC DOLORBOX) ->GetWindowRect ( Scm_color_box_rec) ,- m_color_box_rec . right -= m_color_box_rec . left ,- //ScreenToClient ( Scree) ,- m_color_box_rec . bottom - = m_color_box_rec . top ,-' m_color_box_rec . left = m_color_box_rec . top = 0 ; color_the_box (m_box_color , 1) ;
CFormView: :OnDraw(pDC) ; }
/♦void COentryView: :OnResetb () m_meε_sent = 0 ,- m_mes_rec = 0 ; m_rec_sent = 0 ; m_rec__rec = 0 ,-
SetDlgltemlnt (IDCJMESJREC, 0) ;
SetDlgltemlnt ( IDC_RECJREC, 0) ;
SetDlgltemlnt ( IDC_MES_SENT, 0) ;
SetDlgltemlnt (IDC_REC_SENT, 0) ;
OnAnyUserAction ( ) ;
void COentryVie : : OnTranb 0
{ m_tran_state = 1; GetDlgltem (IDC_TRANB) ->ShowWindow (SWJHIDE) ; GetDlgltem (IDC_ABORTB) - >ShowWindow (SW_SHOW) ; GetDlglte ( IDCJDOMMITB) - >ShowWindo (SW_SHOW) ; OnAnyUserAction () ,-
void COentryView: :OnCommit (int action) {
// Anyway get rid of the commit/abort buttons GetDlgltem (IDCJTRANB) - >ShowWindow (SW_SHOW) ; GetDlgltem ( IDC_ABORTB ) - >ShowWindow ( SWJHIDE) ; GetDlgltem ( IDCJCOMMITB ) - >ShowWindow ( SW_HIDE) ;
/ / Do the commi t i f ( (Q) c c (m_t ran_state > 1 ) ) Qcommit ( act ion ) ; m_tran_rec = 0 ; m_tran_sent = 0 ; m tran state = 0;
} void COentryView: :OnCommitb ()
{
OnCommit (QJCOMMIT) ;
} void COentryView: :OnAbortb ( )
(
OnCommit (Q_ABORT) ; m_mes_sent -= m_tran_sent; m rec rec - = mjtran_rec ;
} " void COentryView: :OnLButtonDown (UINT nFlags, CPoint point)
(
CRect rec; // WINDOWPLACEMENT GetWindowPlacement CRect // MessageBeep (0) ;
GetDlgltem (IDCJCOLORBOX) ->GetWindowRect ( Scree) ;
ScreenToClient (Scree) ; if (rec. PtlnRect (point) ) OnColor 0 ;
CFormView: : OnLButtonDown (nFlags , point) ;
void COentryView: : OnRButtonDown (UINT nFlags, CPoint point)
ClearDisplay ( ) ;
CFormView: : OnRButtonDown (nFlags , point) ;
void COentryView: : ClearDisplay ( )
(
GetParentFrame ( ) - >SetMessageText ( " " ) this->Invalidate 0 ; OnAnyUserAction ( ) ;
void COentryView: -. OnShowdb 0
{
GetDlgltem (IDCJSHOWDB) - >EnableWindo (FALSE) ; SetTimer (DBJDONEJTIMER, 2000, NULL) ; // When the DB is done re-enable // CDbDlg dbd; // dbd. DoModal () ; dbd. Create (IDD_DBDLG) ;
//GetParentFrame () ->SetMessageText ("After dbd. Create " ) ;
OO030Z } void COentryView: :OnOptionsb ( )
{
GetDlgltem (IDCJDPTIONSB) - >EnableWindow (FALSE) ; SetTimer (OPTIONSJDONEJTIMER, 2000, NULL) ; // when the options are done re-en
// o_dlg . Create ( IDDJDJDLG) ; if (o_dlg.m_inst != m_inst) { // Init o_dlg.m_inst = m_inst; // o_dlg .m_parentptr = this; o dig. Create (IDD O DLG) ;
} g_new_color = m_color; o_dlg.ShowWindow(SW_SHOW) ,- }
// oentrvw . h : interface of the COentryView class
//
/////// //// /// / /// ///////// /////// ///////////// ////// / ///// // / / /////// // /// // ttdef ine MESSAGEREADY WMJUSER + 3000
//ttdefine IDDJTPSTIMER 100 class COentryView : public CFormView
{ protected: // create from serialization only
COentryVie () ;
DECLARE DYNCREATE (COentryView) public :
//{ (AFXJDATA (COentryView) enum ( IDD = IDDjOENTRY_FORM } ; int mJDrderMode;
CString m_inst;
BOOL m_sendreply;
//} } AFXJDATA
BOOL m_runflag; // Running or not int m_millisec; // Delay when ordering int m_mes_sent ; int m_mes_rec ; int m_rec_sent ; int m rec rec;
HBRUSH m orush; COLORREF m_color; COLORREF m_box_color; CString m_que; CRect m color box rec;
int m_order; int m_order_num; int m_tran_state; int m_tran_rec; int m_tran_sent; int m_auto_tran; int m_auto_rand; int m_auto_commit ; void AutoRun ( ) ; void colorjthe oo (COLORREF c, BOOL update); void C dLinednt pass); void OnCom it (int action); void OnAnyUserAction () ; void OnColor () ; void ShowRateBa (int act) ; void PlaceOrFillMode (int mode) ; int DbOrder (char cust, char item, int qty) ,- int OraOrder (char cust, char item, int qty) void LoadQList (int mode) ,- void ClearDisplay () ;
CDbDlg dbd; COdlg o_dlg;
// Attributes public :
COentryDoc^ GetDocument ( ) ;
// Operations public :
// Overrides
// ClassWizard generated virtual function overrides
//( (AFXJVIRTUAL (COentryView) public : virtual void OnlnitialUpdate 0 ; protected: virtual void DoDataExchange (CDataExchange^ pDX) ; // DDX/DDV support virtual BOOL OnPreparePrinting (CPrintlnfo^ plnfo); virtual void OnBeginPrinting (CDC^ pDC, CPrintlnfo^ plnfo); virtual void OnEndPrinting (CDC^ pDC, CPrintlnfo^ plnfo); virtual void OnPrint (CDC+ pDC, CPrintlnf o* ) ; virtual void OnDraw(CDC+ pDC) ;
//} }AFX_VIRTUAL
// Implementation public : virtual ~COentryView () ; ttifdef JDEBUG virtual void AssertValid ( ) const; virtual void Dump (CDumpContextSc dc) const; ttendif protected :
, UINT nCtlColor);
IParam);
point);
point);
Figure imgf000307_0001
ttifndef JDEBUG // debug version in oentrvw. cpp inline COentryDoc+ COentryView :: GetDocument () ( return (COentryDoc^ ) m_pDocument ; } ttendif iiiiiiiiiiiiiiiiiiiiimmmmimmmiiiiiiiiiiiimiiiiiimiiiiiimi
// oentrvw. cpp : implementation of the COentryView class
//
/* **
♦♦ Copyrigh (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
♦♦ UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
♦♦ LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
♦♦ IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
♦♦ OR DISCLOSURE.
**
♦♦ THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
♦♦ TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
♦♦ OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
♦♦ EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
♦♦ OpenMQ Demo
♦♦ Module: oenrvw.cpp
♦♦ Author: Derek Schwenke 10/8/95
* *
*/ ttinclude "stdafx.h" ttinclude "oentry. h" ttinclude "oentrdoc.h" ttinclude "dbdlg.h" ttinclude "odlg.h" ttinclude "oentrvw. h" ttinclude "orderfm.h" ttinclude "oraomq.h"
//+++++++++++++ QLIB +++++++++++++++++++ ttinclude "qlib.h" ttinclude "rt.h" extern IpSMBUFH smjbase; lpQHANDLE Q,Qrep;
//+++++++++++++ QLIB +++++++++++++++++++ ttdefine REPLY_SUBMODE 1 ttdefme NOMSGQ_SUBMODE 2 ttdefine DIRECT_FILL_TIME_OVER 121 ttdefine PLACE DRDERJJOQ 0 ttdefine PLACEJDRDER 1 ttdefine FILLJDRDER 2 ttdefine FILL_FROM_ORACLE 3 ttdefme DBJDONEJTIMER 201 ttdefine WAIT_ANAMATE_TIMER 202 ttdefine DIRECT_FILL_TIMER 203 ttdefine FILLJDELAYJTIMER 204 ttdefine FILL_ANAMATE_TIMER 205 ttdefine SET_1ST_TITLE_TIMER 206 ttdefme OPTIONS_DONE_TIMER 207 ttdefine POLL_F I LL JT I MER 208 ttdefme PLACE TIMER 209
ttdef ine NEXTBIT (X ) ( 1 & ( X = X / 2 ) ) ttifdef JDEBUG ttundef THISJFILE static char BASEDJTODE THIS_FILE [ ] = FILE ; ttendif
///////////////////////////////////////////////////////////////////////////// // COentryView
IMPLEMENTJDYNCREATE (COentryView, CFormView)
Figure imgf000310_0001
///////////////////////////////////////////////////////////////////////////// // COentryView construction/destruction
COentryView: : COentryView ()
: CFormView (COentryVie :: IDD)
{
//( (AFX_DATAJINIT (COentryView) mJDrderMode = 1 ; m_inst = _T("") ; m_sendreply = 0 ,-
//}}AFX_DATA_INIT
// TODO: add construction code here m_runflag = 0 ; m_mes_sent = 0 ; m_mes_rec = 0; m_rec_sent = 0 ; m rec rec = 0 ,-
~ " 000308
m_color = RGB (0 , 255 , 0) , m_box_color = m_color, m_que = " " ,- m_order_num = 0 , m_tran_state = 0, m auto tran = 0,
CString g_cust[] = ( "Jones" , "James ", "Johnson" , "Jacobs" , 'Jaf fe" , "Jackson" } , CString g_ιtem[] = { "Bolts ", "Buckets" , "Buttons" , "Belts' . "Bobbins" , "Boats" } , t g_prιce[] = (1,2,3,4,5,6},- t g_qty[] = {1000,1000,1000,1000,1000,1000}; int g_purchases [] = (0,0,0,0,0,0},- t g_num_purchases [] {0,0,0,0,0,0} t g_total_sales = 0, mt g_db_run = 0 , int g_optιons_run = 0, // t g_delay = 0, mt g_dιrectplace = 0, // Client int g_waιt_anamate = 0, // Server t g_dιrect_fill = 0, // Server mt g_fιll_anamate = 0, // Server mt g_fιllιng = 0, // Server mt g_place_tpm = 60; t g_place_delay = 1000,
,
Figure imgf000311_0001
] = "scott/tιger@t :grampa : orcl" ;
COLORREF g_new_color; CFont g_tιtle_font;
CFont g_text_f ont ; int WAITS [] = (lDCJWAIT0,IDCJWAITl} ; mt FILLS [] = {IDC_FILL0,IDC_FILL1,IDC_FILL2} ,- mt ALL_TEXT[] = { IDC_M0DEB0X, IDC_PLACER, IDC_PLACENOQR,IDC_FILLR,IDC_FILLDB
IDCJDPTIONSB, IDC_0RDERB0X, IDC_FILLTXT, IDC_SENDREPC, IDCJORDERB , IDC_AUT0B, IDC_
IDC_QUE, IDCJDUST, IDC_ITEM, IDC_QTY,
IDC_QUELAB, IDCJCUSTLAB, IDC_ITEMLAB, IDC_QTYLAB,
IDCJTRANBOX, IDCJTRANB, IDC_COMMITB, IDC_ABORTB , IDCJEXITB ,
IDC_STATBOX, IDC_RECIPTS_LAB, IDC_RECIPTS, IDCJRECIPT, IDC_MSGSJLAB , IDC_MSGS, 0 } ;
lpQHANDLE gJLQ, // Listener que global for close OnExit ()
COentryView : : "COentryView ( )
void COentryView..DoDataExchange (CDataExchange^ pDX)
(
// ;
Figure imgf000312_0001
///////////////////////////////////////////////////////////////////////////// // COentryView printing
BOOL COentryView: :OnPreparePrinting (CPrintlnfo^ plnfo)
// default preparation return DoPreparePrinting (plnfo) ,-
void COentryView: :OnBeginPrinting (CDC^ /pDCV, CPrintlnfo^ /♦plnfoV)
// TODO: add extra initialization before printinσ } void COentryView: :OnEndPrinting (CDC^ /pDCi/, CPrintlnfo^ /♦plnfoV)
// TODO: add cleanup after printing
void COentryView: :OnPrint (CDC^ pDC, CPrintlnfo^)
// TODO: add code to print the controls } n immmiiiimmmmimmmmi II
II COentryView diagnostics ttifdef JDEBUG void COentryView: :AssertValid () const
CFormView: :AssertValid ( ) ; } void COentryView: :Dump (CDumpContextS dc) const CFormView: :Dump(dc) ;
COentryDoc^ COentryVie ::GetDocument 0 // non-debug version is inline
ASSERT (m_pDocument->IsKindOf (RUNTIME_CLASS (COentryDoc) ) ) ,- return (COentryDoc^) tnjpDocument ,- ttendif //JDEBUG
///////////////////////////////////////////////////////////////////////////// // COentryView message handlers void COentryView: :OnExitb()
CString s ; if (gJLQ) Qclose (ScgJLQ, 0) , if (m_runflag) { m_runflag = 0 while ( s ' = "Auto" ) { // Read the button until not runnnmg
GetDlgltemText (IDC AUTOB , s GetBuffer ( 100) , 100) , }
}
AfxGetMamWnd ( ) - >DestroyWmdow ( ) ,
//GetParentFrame 0 ->SetMessageText ( "Unknown message") , long COentryView- OnReplyMsg (WPARAM wParam, LPARAM IParam) { CString s , ss , switch (wParam) { case REPLY_SUBMODE if (IParam)
SetDlgltemText (IDC_RECIPT, (char ) IParam), else
SetDlgltemText (IDCJRECIPT, "OnReplyMsg Unknown REPLY_SUBMODE Message" SetDlgltemlnt ( IDC_RECIPTS , ++m_rec_rec) , break, case NOMSGQ_SUBMODE if (IParam)
MessageBox) "NOMSGQ_SUBMODE How did I get here7"),
/*
SetDlgltemlnt (IDCJMSGS, ++m_mes_rec) , if (g_delay) {
SetTimer (FILLJDELAYJTIMER, g_delay, NULL) , // g direct f
SetTimer (FILL_ANAMATE_TIMER, 100, NULL) , } else g_dιrect_fill = 0, mt instock = DbOrder (( (pOFORM) IParam) ->cust , ( (pOFORM) IParam) ->ιtem if (instock == 1) ss = "FILLED", else if (instock == 0) ss = "OUT OF STOCK", else if dnstock == -1) ss = "WRONG CUSTOMER", else if dnstock == -2) ss = "WRONG ITEM",
s Format ("Direct %s %s %s %d" , LPCTSTR (ss) , ( (pOFORM) IParam) ->cust, ( SetDlgltemText (IDC_FILLTXT, LPCTSTR (s) ) , color the bo ( ( (pOFORM) IParam) ->color, 0) , */ break, case DIRECT_FILLJTIMEJDVER
GetParentFrame 0 ->SetMessageText (IParam) ,
// SetDlgltemlnt (IDC_MSGS, --m_mes_sent) , break ,- default : if ( IParam) s .Format ("ORM: %d %s" , wParam, IParam) else s . Format ( "Unknown Message ORM"); GetParentFrame () - >SetMessageText (s) ;
} return ( 0 ) ;
}
III i minium i mmmmimmm LISTENER THREAD in immmimmm / m mini nm i II mmimmmm II II minium immmiii II II II i typedef struct tparam { // Thread parameters
HWND hwnd I int bnum // smbuf num to send replys to. CString inst TPARAM, ♦pTPARAM;
TPARAM tp; // <-- Global Data so it does not go away.
char g_thd_data[1000] ,- 111111111111111111111 MSGH g_thd_mh; // Listener thread //
DWORD Listen (pTPARAM tp) ( 1111111111111111 II 111 int max_dly, md, stat=0 ,-
CString s,n = tp->inst;
if ( g_LQ = Qopen (n. GetBuffer (0) ,GET_M0DE, 0, 0 , Sstat , 0 , 0) ) { // Save the buffer I will listen to. tp->bnum = gJLQ->bufs_found [0] ,- // Replys will be sent to this buffer if (SHAREDATA(diag) ) ( s. Forma ("Thread Open(%s) bnum=%d" , LPCTSTR (n) , tp->bnum) ;
:: PostMessage ( tp->hwnd, MESSAGEREADY, 0 , (LPARAM) LPCTSTR(s) );
}
/ // REPLY_SUBMODE (pass sub_mode as ORMJMESJREC while (QSUCCESS == Qget (gJLQ, Scg_thd_mh, data, 1000) ) {
:: PostMessage (tp->hwnd, MESSAGEREADY, g_thd__mh . sub_mode , (LPARAM) data); // :: PostMessage (tp->hwnd,MESSAGEREADY, ORM_MES_RECEIVED, (LPARAM) data);
* /
while (QSUCCESS == QlistenBeforeReply (gJLQ, Scg_thd_mh, g_thd_data, 1000) ) { // Got a message could be Recipt or direct fill request if (g_thd_mh.sub_mode == REPLYJSUBMODE) {
:: PostMessage (tp->hwnd, MESSAGEREADY, g_thd_mh. sub_mode , (LPARAM) g_c
} else { g_direct_fill = 1; max_dly = 500; // 25 Seconds max check 20 times a second while ( (g_direct_fill | | g_filling) ScSc (--max_dly)) Sleep(50); // if (max_dly > 0) md = ACK_M0DE; else { md = NACK_M0DE; g_direct_fill = 0;
MessageBox (NULL, "SER TIME OVER", NULL , NULL) ; s. Format ("%s: SERVER did not reply to DIRECT FILL",n); :: PostMessage (tp->hwnd, MESSAGEREADY, DIRECTJFILLJTIMEJDVER , (LPARA
QreplyAfterListen (g_LQ,md, 0 , gjthd_data, g_thd_mh. size, 0) }
} else { s. Format ("Cant Qopends) ERROR=%d" , LPCTSTR (n) , stat ) ; MessageBox (tp->hwnd, s, "Listener Thread" , MBJICONSTOP) ;
Qclose ( egJLQ, 0) return (0) ,-
void COentryView: : CmdLine (int pass) { CString parm, value, line, nline ; int i , r , g , b ,- line = AfxGetApp 0 - >m_lpCmdLine ,-
' while (2 <= (i = sscanf (LPCTSTR (line) , "%s %s % ["©] ", parm.GetBuf fer (100) , value . GetBuf fer (100) , nline .GetBuf fer ( 100) ) ) ) { parm.MakeUpper 0 ;
// oentry Name xxx Que ssss RGB r,g,b OrderMode m Fill x Poll x Order x if (pass == 1) { if (parm == "NAME") (m_inst = LPCTSTR (value) ; } if (parm == "RGB") { sscanf (LPCTSTR (value) ," %d, %d, %d" , Sr , &g, &b) ,-m_colo if (parm == "ORDERMODE") { sscanf (LPCTSTR (value) , "%d" , ScmJDrderMode) ;m_Or if (m_OrderMode < 0 | | m_OrderMode > 3) mJDrderMod if (parm == "FILL") (sscanf (LPCTSTR (value) , "%d" , &g_f ill_delay) ; } if (parm == "POLL") (sscanf (LPCTSTR (value) ," %d" , Scg_poll_pps) ; if((MIN_POLL <= g_poll_pps) ScSc (g_poll_ppε <= MAX_ g_poll_delay = 1000/g_poll_pps; } if (parm == "ORDER") ( sscanf (LPCTSTR (value) , "%d" , Scg_place_tpm) ; if((MIN_AUTO <= g_place_tpm) ScSc (g_place_tpm <= MA g_place_delay = 60000/g_place_tpm; } if (parm == "ORACLE") { strcpy (g_oracle_con_str , PCTSTR (value) ) ; }
} else { if (parm == "QUE" | | parm == "SERVER") {
CComboBox ^ 08 = (CComboBox ) this->GetDlgItem (IDC_QUE) ; CB->SelectString(-l, value) ; OnSelchangeQue ( )
line = LPCTSTR (nline) nline = " " ,-
void COentryView: : LoadQList (int mode)
{
// mode=0 : List Non-Ques
// mode=l : List Ques int i ;
CComboBox + 08 = (CComboBox ) this->GetDlgItem ( IDCjQUE) ; CB->ResetContent () ;
// List all logical queues
// APPS: [physical] , logicall , logical2 , [physical] , logical, if (smjDase = AttachSharedMemory ()) { IpRT rt = RTROOT; while (rt = NextRT (rt)) ( char ♦e^s = RT_APPS(rt); // Starts after the first letter while (s = strchr (s, ',') ) { // Ends at next "," if (e = strchr (++s, ',') ) { e = 0; if ( ( !strchr(s, ' [') ) ScSc +s) { if ((mode ScSc strchr (s ,' Q' ) ) || (Imode &S: ! strchr (s ,' Q ' ) CB->AddString(s) ,- // lb- >InsertString ( -1 , s)
// Now add any extra entries from the local node that were not in the RT // IpSMBUF BUF; for (i = 0; i < SHAREDATA (nsbuf) ; i++) ( if (! strcmp ( (SMBUFADDR (i) ) ->name, "empty") ) continue; if ( !strcmp( (SMBUFADDRd) ) ->name, "QNETD") ) continue; if (CBJERR != CB->FindStringExact (-1, (SMBUFADDRd) ) ->name) ) continue; / if ((mode ScSc strchr ( (SMBUFADDR (i) ) ->name ,' Q' ) ) || (!mode ScSc !strchr((SM CB->AddString( (SMBUFADDRd) ) ->name) ; // lb->InsertString ( -1 , s)
}
} else (
MessageBox ("QNETD not running. Please restart."),-
CB->AddString("") ; if ( CBJERR == (i = CB->FindStringExact ( -1 , m_que) ) )
CB->SetCurSel(0) ; else
CB->SetCurSel (i) ;
OnSelchangeQue 0 ;
void COentryView : : OnlnitialUpdate ( )
(
CString s ;
CFormView: : OnlnitialUpdate 0 ,-
// Set frame size = Form size GetParentFrame ( ) - >RecalcLayout ( ) ,- ResizeParentToFit (FALSE) ; ResizeParentToFit (TRUE) ; mJDrderMode = PLACEJDRDER;
LoadQList (1) ;
CmdLine (1) ,-
// Set max size on data fields
( (CEdit ♦) this->GetDlgItem(IDC_CUST) ) ->LimitText (9) ;
( (CEdit ) this->GetDlgItem(IDC_ITEM) ) ->LimitText ( 9) ;
( (CEdit ) this->GetDlgItem(IDC_QTY) ) ->LimitText (9) ,-
// Generate unique instance name on this node if (m_inst == "") // May be set by command line "name" m_inst .Format ("OE%d" , SHAREDATA (ap . app_num) ++) ;
OnAnyUserAction ( ) ,-
SetTimer (SET_1ST_TITLE_TIMER, 100, NULL) ; // Calls OnAnyUserAction () ; to set t
// Start the backgound thread to Qget 0 messages
DWORD id; tp . hwnd = m_hWnd,- tp.inst = m_inst;
CreateThread (NULL , 0 , (LPTHREAD_START_ROUTINE ) Listen , ( LPVOID) Sctp , 0 , Scid) ;
CmdLine ( 2 ) ;
( (CButton ) this->GetDlgItem(IDC_PLACER) ) - >SetCheck (0) ;
( (CButton ) this->GetDlgItem(IDC_PLACENOQR) ) ->SetCheck (0) ;
( (CButton ♦) this->GetDlgItem(IDC_FILLR) ) - >SetCheck (0) ;
( (CButton ♦) this->GetDlgItem(IDCJFILLDB) ) ->SetCheck (0) ; if (mJDrderMode == PLACEJDRDER)
( (CButton ) this->GetDlgItem(IDCJPLACER) ) ->SetCheck (1) ; if (mJDrderMode == PLACEJGRDER_NOQ)
( (CButton ♦) this->GetDlgItem(IDC_PLACENOQR) ) ->SetCheck (1) ; if (m_OrderMode == FILLJDRDER)
( (CButton ♦) this->GetDlgItem(IDC_FILLR) ) ->SetCheck (1) ; if (mJDrderMode == FILL_FROM_ORACLE)
( (CButton ) this->GetDlgItem(IDC_FILLDB) ) ->SetCheck (1) ; ttifdef ORACLE
( (CButton ) this->GetDlgItem(IDC_FILLDB) ) ->EnableWindow (TRUE) ,- ttelse
( (CButton ) this->GetDlgItem(IDC_FILLDB) ) ->EnableWindo (FALSE) ; ttendif
PlaceOrFillMode (mJDrderMode) ,-
// Fonts
LOGFONT If; memset (Self, 0, sizeof (LOGFONT) ) ; ttifdef BIGFONT lf.lfHeight = 18; ttelse lf.lfHeight = 13; ttendif g_text_font . CreateFontlndirect (Self) ; strcpy (If . IfFaceName, "Monotype Corsiva") ; lf.lfHeight = 32; g_title_font . CreateFontlndirect (Self) ,-
GetDlgltem ( IDC_BIGJTITLE) ->SetFont (Scg_title_font ) ; int i = 0 ,- while (ALL_TEXT[i] )
GetDlgltem (ALLJTEXT [i++] ) ->SetFont dg_text_font ) ;
//void COentryView: :OnEditchangeQue 0 void COentryView: : OnEditupdateQue 0
OnSelchangeQue ( ) ;
void COentryView: : OnSelchangeQue ( )
CString que,s; int stat=0;
// Get the que name
GetDlgltemText (IDC_QUE, que .GetBuffer (100) , 100) que .ReleaseBuffer () ;
if (que != m_que) { // New value if (Q) Qclose (ScQ, 0) ,- if (que == "") { // No que m_que = " " ,- s = "No Que will be used" ;
GetDlgltem (IDC_AUTOB) ->EnableWindow(FALSE) ,- GetDlgltem (IDCJDRDERB) ->EnableWindow(FALSE) ;
} else { // Set value
s . Format ( "Opening que %s",que); GetParentFrame () ->SetMessageText (s) ; if (Q = Qopen (que. GetBuf fer (0) , PUTJMODE, 0, 0, ScStat, 0,0) ) ( if (m_sendreply)
Q->msgh. reply_smbuf = tp.bnum; m_que = que ; s . Format ( "Qopen (%s) " , que) ;
GetDlgltem (IDC_AUTOB) ->EnableWindow (TRUE) ; GetDlgltem (IDC_ORDERB) ->EnableWindow (TRUE) ,- if (mJDrderMode == PLACEJDRDER JTOQ) Q->msgh.sub_mode = NOMSGQ_SUBMODE ,-
} else { s . Format ( "Qopen (%s) Error %d" , que, stat) ,- GetDlgltem(IDCJAUTOB) ->EnableWindow (FALSE) ; GetDlgltem (IDC_ORDERB) - >EnableWindow (FALSE) ;
GetParentFrame ( ) ->SetMessageText (s) ;
}
OnAnyUserAction ( ) ;
}
OFORM g_buf ;
DWORD DirectPlace () { int flags = 0 ,-
QsendAndReceive (Q, 0 , SUB_MODE_OK , flags, sizeof (gjbuf) , (char ) SegjDuf, 0,0,0, g_directplace = 0; return (0) ,- }
//ORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDER //ORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDER //ORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDER //ORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDER //ORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDERORDER void COentryView: :OnOrderb( )
{ // Check m_ordermode = 0 to place order or = 1 to fill the order CString que, str, s = ""; int gsize, stat=0, flags, instock, filled=0; // OFORM buf ,- char line [sizeof (OFORM) +10] ,-
MSGH mh; // To get detailed put status
DWORD id; if (g_directplace) return; // direct place thread is already working if (g_filling) return; // Wait for fill done is already working if (Q) ( if (!m_runflag) OnAnyUserActio () ; if (m_auto_tran) { if (m_auto_rand < 16) m_auto_rand = rand(); // Begin a tran? if ( (m_auto_tran == 1) S=Sc NEXTBIT (m_auto_rand) ) { if ( !m_tran_state) m_tran_state= 1; // Done by OnTran (causes m_auto_tran = 2;
GetDlgl tem ( IDCJTRANB ) - >ShowWindow ( SW_HIDE ) ; if (m_auto_commit = NEXTBIT (m_auto_rand) )
GetDlglte (IDC_COMMITB) ->ShowWindow (SW_SHOW) ; else
GetDlgltem (IDC_ABORTB) ->ShowWindow (SW SHOW) ;
}
}
// Set the flags for get or put if (m_tran_state) if (m_tran_state++ == 1) flags = Q_TRAN_BEGIN; else flags = QJTRAN; else flags = 0 ,-
if (mJDrderMode <= PLACEJDRDER) { // Place the order
// Read the data to be sent
GetDlgltemText (IDC_CUST,g_buf. cust, 10) ,-
GetDlgltemText (IDCJITEM, g_buf . item, 10) ; gjbuf. qty = GetDlgltemlnt (IDC_QTY, NULL, TRUE) ; gjbuf. color = m_color; g_buf . reply_to = SHAREDATA (hostip) ;
SetDlgltemlnt (IDC_MSGS, ++π_mes_sent ) ,- if (mJDrderMode == PLACEJDRDER_NOQ) { g_directplace = 1;
GetDlgltem (IDC_ORDERB) - >EnableWindo (FALSE) ;
SetTimer (WAIT_ANAMATE_TIMER, 00, NULL) ;
CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) DirectPlace, (LPVOID) 0
} else if (QSUCCESS == (stat = QsendAndReceive (Q, 0 , SUB_MODE_OK, flags, s if (mh.mode == ACK_MODE ScSc mh.sub_mode == SUB_MODE_OK) ( m_tran_sent++ ,- s. Format ("%s: %8s %8s %d" ,m_que .GetBuffer (0) , g_buf .cust , g_buf . ite } else { if (mh.sub_mode == SUB_MODE_FULL) if (m_runflag) s. Format ("que is FULL"); else
MessageBox ("que is FULL"); else s. Format ("Qput () error mode=%d submode=%d" , mh. sub_mode) ;
} else { // not QSUCCESS (communications error) SetDlgltemlnt (IDC_MSGS, --m_mes_sent) ; s. Format ("Communication error code %d",stat); GetParentFrame () ->SetMessageText (s) ,-
} else { // FILLJDRDER Fill the order ♦g_buf.cust = gjbuf. item = 0 ; g_buf .qty = 0 ; if (g_direct_fill) { // There was a direct placed order to fill pOFORM po = (pOFORM) Scg_thd_data; CString ss;
SetDlgltemlnt (IDC_MSGS, ++m_mes_rec) ; if (g_fill_delay) ( g_filling = 1; // Do not fill another until the timer expires SetTimer (DIRECT_FILL_TIMER,g_fill_delay, NULL) ; // g_di
SetTimerfFILL ANAMATE TIMER, 100 , NULL) ;
} color_the_box( po->color, 0) ; int instock = DbOrder (po->cust, po->item, po->qty) ; if dnstock == 1) ss = "FILLED"; else if dnstock == 0) ss = "OUT OF STOCK"; else if dnstock == -1) ss = "WRONG CUSTOMER"; else if dnstock == -2) ss = "WRONG ITEM" ; filled++; s. Format ("Direct : %s: %s %s %d" , LPCTSTR (ss) , po->cust, po->item, po- SetDlgltemText (IDC_FILLTXT, LPCTSTR (s) ) ;
g_direct_fill = 0 ; if (g_filling) return;
}
if (QSUCCESS == (stat = QsendAndReceive (Q, REQUEST_MODE, SUB_MODE_OK, flag sizeof (gjbuf) , (char ♦) Seg_buf, Segsize, Sctnh) ) ) ( if (mh.mode == ACK_MODE ScSc mh.sub_mode == SUB_MODE_OK) { SetDlgltemlnt (IDC_MSGS, ++m_mes_rec) ; if (gsize < sizeof (OFORM) ) s. Format ("Bad reply length"); else ( // you got valid message m_tran_rec++; color_the_box(g_buf .color, 0) ,- // But dont force it if (mJDrderMode == FILL_FROMJDRACLE) instock = OraOrder (gjuf .cust, gjouf . item, gjbuf .qty) ; // Ora else instock = DbOrder (gjbuf. cust, gjbuf. item, g_buf .qty) ,- if (g_fill_delay) { gJEilling = 1; // Do not fill another until the timer ex
SetTimer (FILLJDELAYJTIMER, g_fill_delay, ULL) ; //
SetTimer (FILL_ANAMATE_TIMER, 100,NULL) ;
}
} } else if (mh.sub mode == SUB_MODE_EMPTY) { if (m__runflag J| filled) s . Format ( "Que Empty" ) ; else
MessageBox ( "Que Empty"); } else s. Format ("Bad reply mode %d: %d" , mh.mode, mh. sub_mode) ;
} else ( // not QSUCCESS (communications error) mh.mode = 0;// Not ACK_MODE s. Format ("Communication Error Code %d",stat);
} if (gsize == sizeof (OFORM) ) { if (instock == 1 ) sprintf (line, "FILLED: %9s %9s %d" ,g_buf . cust, g_buf . item, gjbuf .qty) else if ( instock == 0) sprintf (line, "OUT OF STOCK :%9s %9s %d" , g_buf . cust , g_buf . item, g_bu else if ( instock == -1) sprintf (line, "NO SUCH ITEM:%9s %9s %d" , g_buf . cust , g_buf . item, g_bu else // instock == -2 sprintf (line, "NO SUCH CUSTOMER:%9s %9s %d" , gjbuf . cust , g_buf . item, SetDlgltemText (IDC_FILLTXT, line) ;
}
// else
// strcpy (line, "") ;
// Send Reply if requested if ( (mh.reply_smbuf >= 0 ) && (mh. reply_smbuf < SHAREDATA (nsbuf) ) cSc mh. mid. host = g_buf . replyjto; ■// HACK! Makes sure sending host gets
Qrep = QopenReply (Qrep, Scmh, 0, 0, 0) ,-
if (QSUCCESS != (stat = Qput (Qrep, 0 , EPLY_SUBMODE, 0 , sizeof (line) , lin s .Format ("Qput (%s) Error %d" , Qrep- >msgh. to_server, stat) ; else s. Format ("Replying Qput(%s) to smbuf %d" , Qrep->msgh . to_server,Qre
SetDlgltemlnt (IDC_RECIPTS, ++m_rec_sent) ;
}
GetParentFrame 0 ->SetMessageText (s) ; /* if (m_runflag &Sc mh.mode == ACK_MODE) // We got something
OnOrderbO; // Check again for next message, no need to wait, else // We didnt get anything color_the_box ( m_color,0); // restore old color
*/ if (!m_runflag ScSc !g_fill_delay) color_the_box ( m_color,0);
} // place or fill
if ( (mJDrderMode <= PLACE_ORDER) || mh.mode == ACK_MODE) // Placeing or ^o if (m_auto_tran > 1) { if ( ( NEXTBIT (m_auto_rand) S=Sc NEXTBIT (m_auto_rand) ) I I (m_auto_tran++ > 8) ) { // Commit or Abort tran? if (m_auto_commit )
OnCommitb ( ) ; else
OnAbortb ( ) ; m auto tran = 1 ;
if ( (mJDrderMode >= FILLJDRDER) ScSc m_runflag &Sc mh.mode == ACK_MODE ScSc mh.subjnode == SUB_MODE_OK) if (g_max_orders++ < 200)
OnOrderbO ; // Try to get one more item, else g_max_orders = 0 ; } else g_max_orders = 0 ;
// The order or fill button will be active until we are done. // CButton ^ 06 = (CButton ) this->GetDlgItem (IDCJDRDERB) ; // CB->SetState(TRUE) ;
}
//
// m_auto_tran:
// 0 No auto trans
// 1 No tran yet
// 2 After OnAutobO
// int g_poll_delay_old; int g_place_delay_old; void COentryView: :0nTimer (UINT nIDEvent)
{ if (nIDEvent == PLACEJTIMER ) { if (g_directplace) return; // direct place thread is already working if (g_filling) return; // Wait for fill done is already working if (g_place_delay_old != g_place_delay) (
KillTimer (PLACEJTIMER) ;
SetTimer (PLACE TIMER,g place delay old = g place delay, NULL) ; }
SetDlgltemText ( IDC_CUST, g_cust [m_order_num % 6] ) ; SetDlgltemText DC_ITEM, g_item [m_order_num % 5] ) ; SetDlgltemlnt ( IDCJQTY, 1 + (m_order_num++ % 9 ) , FALSE) ;
OnOrderb ( ) ;
//CButton ^ 08 = (CButton ) this->GetDlgItem (IDCJDRDERB) ;
//CB->SetState(TRUE) ;
} else if (nIDEvent == POLL_FILL_TIMER) { if (!g_filling) ( if (g_poll_delay != g_poll_delay_old) {
KillTimer (POLL_FILL_TIMER) ;
SetTimer (POLL_FILL_TIMER,g_poll_delay_old = g_poll_delay,NULL) ;
OnOrderb ; }
} else if (nIDEvent == WAIT_ANAMATE_TIMER) { if (g_directplace) (
// Anomate the wait 0,1 0,1
GetDlgltem (WAITS [g_wait_anamate++] ) ->ShowWindow (SW_HIDE) ; if (g_wait_anamate > 1) g_wait_anamate = 0 ;
GetDlgltem(WAITS [g_wait_anamate] ) ->ShowWindow (SW_SHOW) ,- } else {
KillTimer (WAIT_ANAMATE_TIMER) ;
GetDlglte (IDCJDRDERB) ->EnableWindow (TRUE) ;
GetDlgltem (WAITS [g wait anamate] ) ->ShowWindo (SW HIDE); }
} else if (nIDEvent == FILL_ANAMATE_TIMER) { if (g_filling == 0) ( // End Anamation KillTimer (FILL_ANAMATE_TIMER) ; GetDlgltem (FILLS [g_fill_anamate] ) ->ShowWindow (SWJHIDE) ,-
} else { // Anamate 0,1,2
GetDlgltem (FILLS [g_fill_anamate++] ) ->ShowWindow (SW_HIDE) ; if (g_fill_anamate > 2) g_fill_anamate = 0 ;
GetDlgltem (FILLS [g_fill_anamate] ) ->ShowWindow (SW_SHOW) ,- if (1) { // g_progress
// ( (CButton ) this->GetDlgItem(IDC_PLACER) ) ->SetCheck (0) ; // GetDlgltem(IDCJPROG) ) ->SetRange (0 , 100) ; // ((CProgressCtrl ) this->GetDlgItem(IDC_PROG) ) ->SetRange (0, 100) ; // ((CProgressCtrl ) this->GetDlgItem(IDC_PROG) ) ->SetPos (50) ; // ((CProgressCtrl ) this->GetDlgItem(IDC_PROG) ) ->ShowWindow(SW_SHOW
} else if (nIDEvent == DIRECTJFILLJTIMER) { g_direct_fill = 0; // let QsarO return. g_filling = 0; // End Anamation, let next order in KillTimer (DIRECT_FILL_TIMER) ; color_the_box ( m_color,0); // Restore the old color
} else if (nIDEvent == FILLJDELAYJTIMER) { g filling = 0; // End Anamation, let next order in KillTimer (FILL_DELAY_TIMER) ; colorjthejbox( m_color,0); // Restore the old color
} else if (nIDEvent == SET_1ST_TITLE_TIMER) { // Only done once KillTimer (SET_1ST_TITLE_TIMER) ; OnAnyUserAction () ;
} else if (nIDEvent == DBJDONEJTIMER) { if (g_db_run == 40) { g_db_run = 0 ,-
GetDlgltem (IDC_SHOWDB) ->EnableWindow (TRUE) ; KillTimer (DBJDONEJTIMER) ;
} else if (nIDEvent == OPTIONSJDONEJTIMER) { if (g_options_run == 40) { // End g_options_run = 0;
GetDlgltem (IDCJDPTIONSB) ->EnableWindow (TRUE) ; KillTimer (OPTIONS DONE TIMER);
} ~ " if (m_color != g_new_color) ( color the box(m color = g new color, 1);
} " " if (g_clear_stats) { g_clear_stats = 0 ; m_mes_sent = 0; m_mes_rec = 0; m_rec_sent = 0 ; m_rec_rec = 0 ;
SetDlgltemlnt (IDC_MSGS, 0); SetDlgltemlnt (IDC_RECIPTS, 0) ;
} else
CFormView: :0nTimer (nIDEvent) ;
void COentryView: :OnAutob() if (m_runflag) {
KillTimer (PLACEJTIMER) ;
KillTimer (POLL_FILL_TIMER) ; m_runflag = 0; // You are no longer running if (m_auto_tran) OnAbortbO ; m_auto_tran = 0;
SetDlgltemText (IDC_AUTOB, "Auto" ) ;
GetDlgltem (IDC_EXITB) ->EnableWindow(TRUE) ,-
((CButton ) this->GetDlgItem(IDC_PLACER) ) ->EnableWindo (TRUE) ;
( (CButton *) this->GetDlgItem(IDC_PLACENOQR) ) ->EnableWindo (TRUE) ;
((CButton ♦) this->GetDlgItem(IDC_FILLR)) ->EnableWindo (TRUE) ; ttifdef ORACLE
( (CButton ) this->GetDlgItem(IDC_FILLDB) ) ->EnableWindow (TRUE) ,- ttendif color_the_bo ( m_color,l); // Restore default color
} else { m_runflag = 1; // You will be running m_order_num = 0; // 1st order number Controls order selections m auto tran = m tran state; // make random transactions too?. if ( mJDrderMode > PLACEJDRDER ) // FILL
SetTimer (POLL_FILL_TIMER,g_poll_delay_old = g_poll_delay,NULL) ,- else
SetTimer (PLACEJTIMER, g_place_delay_old = g_place_delay, NULL) ,-
SetDlgltemTex (IDC_AUTOB," Stop " ) ;
GetDlgltem(IDC_EXITB) - >EnableWindow(FALSE) ;
( (CButton *) this->GetDlgItem(IDC_PLACER) ) ->EnableWindow (FALSE) ,- ( (CButton *) this->GetDlgItem(IDC_PLACENOQR) ) ->EnableWindow (FALSE) ; ( (CButton *) this->GetDlgItem(IDC_FILLR) ) ->EnableWindow (FALSE) ; ( (CButton *) this->GetDlgItem(IDC_FILLDB) ) ->EnableWindow (FALSE) ,-
OnAnyUserAc ionO ; }
// Color Color Color Color Color Color Color Color Color Color // Color Color Color Color Color Color Color Color Color Color // Color Color Color Color Color Color Color Color Color Color
void COentryView: :OnColor()
CHOOSECOLOR cc; // common dialog box structure COLORREF acrCustClr [16] ;
// Setup the custom colors as a grey scale for (int v=0,i=0; i < 16; v=17 * i++) acrCustClr [i] = RGB(v,v,v);
// Initialize the necessary members. cc.lStructSize = sizeof (CHOOSECOLOR) ; cc.hwndOwner = NULL; // = hwnd; cc.lpCustColors = (LPDWORD) acrCustClr; cc. Flags = CC_FULLOPEN; // CCJPREVENTFULLOPEN
if (ChooseColor (Stcc) ) { CString s; m_box_color = color = cc .rgbResult ; // lpCustColors Invalidate () ; /7 Display the new color } else (
GetParentFrame 0 ->SetMessageText ("Color was not changed") O }nAnyUserActionO ;
//Hinit = 1;
HBRUSH COentryView: :OnCtlColor (CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{ if (nCtlColor == CTLCOLOR_EDIT) { if (pWnd->GetDlgCtrlID() == IDCJCOLORBOX) { pDC->SetBkColor (m_color) ; m_brush = CreateSolidBrush (m_color) ; return (m brush) ;
} else if (nCtlColor == CTLCOLOR_BTN ) ( // CTLCOLOR_EDIT if (pWnd->GetDlgCtrlID() == IDC_AUTOB) if (m_runflag) { pDC->SetBkColor(RGB(255,0,0) ) ; // SetBkColor SetTextColor pDC->SetTextColor (RGB (255 , 255, 255) ) ; // SetBkColor SetTextColor m_brush = CreateSolidBrush (m_color) ; retur (m brush) ;
// )}''-else if (nCtlColor == CTLCOLOR_STATIC ) { // CTLCOLOR_EDIT
// if (pWnd->GetDlgCtrlID() == IDC_INST) {
// // pDC->SetBkColor(RGB(255,0,0) ) ; // SetBkColor SetTextColor
// // pDC->SetTextColor(RGB(255,255,255) ) ; // SetBkColor SetTextColor
// // m_brush = CreateSolidBrush (m_color) ;
// m_brush = CreateSolidBrush (m_box_color) "// empty non-text background
// pDC->SetBkColo (m_box_color) ; // behind the letters
// return (m brush);
// . }
HBRUSH hbr = CFormView: :OnCtlColor (pDC, pWnd, nCtlColor); return hbr;
int COentryView: :DbOrder (char *cust, char *item, int qty) { int custn=0 , itemn=0 ; while (strcmp (item, g_item [itemn] ) ) if (++itemn == 6) return(-l); while (strcmp (cust, g_cust [custn] ) ) if (++custn == 6) return(-2); if (g_qty [itemn] >= qty) { g_qty [itemn] -= qty; g_purchases [custn] += qty * g_price [itemn] ,- g_num_purchases [custn] ++; g_total_sales += qty * g_price [itemn] ,-
} else return (0) ; return (1) ;
int COentryView: :OraOrder (char *cust, char *item, int qty) { int custn=0, itemn=0, price, stock, re, cust_orders,cust_sales; CString s; while (strcmp (item, g_item[itemn] ) ) if (++itemn == 6) return(-l) while (strcm (cust, g_cus [custn] ) ) if (++custn == 6) return(-2)
if (g_ora_state == 0) {
GetParentFrame 0 ->SetMessageText ("Cant Order from oracle: not connected"); return (0) ; // Read Oracle if ( (re = oraread(item, Scprice, ScStock) ) ) { s .Format ("OraRead Error %d",rc);
GetParentFrame 0 ->SetMessageText (s) ; return (0) ; if ( (re = oracustr (cust , SeCust_orders , Secust_sales ) ) ) s . Format ( "OraCustRead Error %d" , rc) ; GetParentFrame - >SetMessageText ( s) ;
if (qty > stock) { return(O); // MessageBox ( "OutOfStock" ) } else { stock -= qty; g_total_sales += qty * price; cust_sales += qty * price; cust orders++;
// Write Oracle if ( (re = orawrite (item, stock)) ) { s .Format ("OraWrite Error %d",rc);
GetParentFrame ( ) - >SetMessageText (s) ; return (0) ;
} if ( (re = oracustw (cust , cust_orders, cust_sales) ) ) s .Format ("OraCustWrite Error %d",rc);
GetParentFrame ( ) ->SetMessageText (s) ;
return (1)
void COentryView: -. PlaceOrFillMode (int mode)
( ' mJDrderMode = mode; int SHOW, HIDE, IsPlaceMode; if (mode <= PLACEJDRDER) (
HIDE = SWJHIDE;
SHOW = SWJSHOW;
IsPlaceMode = TRUE; } else (
HIDE = SWJSHOW;
SHOW = SW_HIDE;
IsPlaceMode = FALSE; }
GetDlgltern ( IDC_SENDREPC) - >ShowWindow (SHOW) ; // Show sendreply checkbox
if (mJOrderMode <= PLACEJDRDER) {
SetDlgltemText (IDCJDRDERB, "Order") ; // Order = Order
SetDlgltemText ( IDCJDRDERBOX, "Place Orders") ; // Order = Order
SetDlgltemText (IDC_BIG_TITLE, "OpenMQ Place Orders"); // Order. } else {
SetDlgltemText (IDCJDRDERB, "Fill") ;
SetDlgltemText (IDCJDRDERBOX, "Fill Orders") ;
SetDlgltemText (IDC_BIG_TITLE, "OpenMQ Fill Orders");
GetDlgltem (IDC_SHOWDB) ->ShowWindow (HIDE)
GetDlgltem DC CUST) ->ShowWindow(SHOW) ; GetDlgltemdDC "ITEM) ->ShowWindow(SHOW) ; GetDlgltemdDC "QTY) ->ShowWindow(SHOW) ; GetDlgltem DC "CUSTLAB) ->ShowWindow(SHOW) ; GetDlgltemdDC "ITEMLAB) ->ShowWindow(SHOW) ; GetDlgltem DC "QTYLAB) ->ShowWindow(SHOW) ;
GetDlgltem) IDCJFILLTXT) ->ShowWindo (HIDE)
// ( (CEdit ♦) this->GetDlgItem(IDC_CUST) ) ->SetReadOnly (FALSE) // ( (CEdit ) this->GetDlgItem(IDCJITEM) ) ->SetReadOnly (FALSE) // ( (CEdit ♦) thιs->GetDlgItem(IDC_QTY) ) ->SetReadOnly (FALSE)
// Stats if (mode <= PLACE ORDER) {
SetDlgltemText ( IDC_MSGS_LAB, "Sent:") ; SetDlgltemText (IDCJRECIPTSJLAB, "Received: ') ; SetDlgltemlnt (IDCJMSGS, m_mes_sent) ,- SetDlgltemlnt (IDC_RECIPTS, m_rec_rec) ; else { SetDlgltemText ( IDC_MSGS__LAB , "Received:") ; SetDlgltemText (IDC_RECIPTS_LAB, "Sent:") ; SetDlgltemlnt (IDC_MSGS, m_mes_rec) ; SetDlgltemlnt (IDC_RECIPTS, m_rec_sent) ;
if (mode •= PLACE_ORDER_NOQ) {
GetDlgltem (IDCJTRANBOX) ->ShowWindow(SW_SHOW) ; if (m_tran_state) (
GetDlgltem (IDC_COMMITB) ->ShowWindow(SW_SHOW) ,- GetDlgltem (IDCJABORTB) ->ShowWindow (SW_SHOW) ;
} else
GetDlgltem (IDCJTRANB) ->ShowWindow (SWJSHOW) ; } else (
GetDlgltem (IDCJTRANBOX) - >ShowWindow (SWJHIDE) ;
GetDlgltem (IDC_TRANB) ->ShowWindow (SWJHIDE) ;
GetDlgltem (IDC_COMMITB) ->ShowWindo (SW_HIDE) ;
GetDlgltem (IDCJABORTB) ->ShowWindow (SW_HIDE) ;
GetDlgltem (IDC_SENDREPC) ->ShowWindow (SWJHIDE) ,-
if (mode == PLACE ORDERJNOQ) { LoadQList (0) ; 7/ Load non-Que
} else {
LoadQList (1) ,- // Load Que names
// DB if (mode <= PLACEJDRDER) if (g_db_run) g_db_run = 40; // Turn off the DB display if it was left on.
if (mode == FILL_FROM_ORACLE) { if (g_ora_state == 0) if (oraconn (g_oracle_con_str) )
MessageBox ( "Oracle Connect Failed"),- else g_ora_state = 1 ; } else { if (g_ora_state == 1) if (oradisc () )
MessageBox ( "Oracle Disconnect Failed"); else g ora_state = 0 ;
OnAnyUserAction ( )
// Re load the que list just incase a new que was launched void COentryView: : OnSetfocusQue 0 if (mJDrderMode == PLACEJDRDER_NOQ) {
LoadQList (0) ; // Load non-Que } else {
LoadQList (1) ; // Load Que names
void COentryView: : OnPlacenoqr () if (! ((CButton ♦) GetDlgltem ( IDC_PLACENOQR) ) ->GetCheck() ) return, PlaceOrFillMode ( PLACEJRDERJNOQ) ,- OnAnyUserActionO , void COentryView: :OnPlacer () if (!( (CButton ♦) GetDlgltem ( IDCJPLACER) ) ->GetCheck() ) return, PlaceOrFillMode (PLACE_ORDER) ; OnAnyUserActionO , } void COentryView-. :OnFillr()
if (!( (CButton *) GetDlgltem (IDCJFILLR) ) ->GetCheck ) return ,-
PlaceOrFillMode (FILLJDRDER) ; OnAnyUserAction ( ) ;
} void COentryView: :OnFilldb()
( if (! ((CButton ♦) GetDlgltem (IDCJFILLDB) ) ->GetCheck 0 return;
PlaceOrFillMode (FILLJFROMJDRACLE) ; OnAnyUserActionO ;
void COentryView: : OnAnyUserAction ( )
SetDlgltemText (IDC_RECIPT, "") ; SetDlgltemText (IDCJFILLTXT, "") ; if (m_que == "")
GetParentFrame 0 ->SetWindowText (m_inst + ": No server is selected" ); else if (mJDrderMode == PLACEJDRDER)
GetParentFrame 0 ->SetWindowText (m_inst + Place orders into queue " + m_ else if (mJDrderMode == PLACEJDRDERJJOQ)
GetParentFrame 0 ->SetWindowText (m_inst + Place orders directly to " + m else // FILL
GetParentFrame 0 ->SetWindowText (m_inst + Fill orders from queue " + . J m box color = tri color ;
) void COentryView : : OnSendrepc ( )
{ m_sendreply = !m_sendreply; // How can I get this info? if ( Q ) if ( m_sendreply )
Q->msgh.reply_smbuf = tp.bnum,- else
Q->msgh . reply_smbuf = -1;
void COentryView: : color_the_box (COLORREF color, BOOL forceit) if (( m_box_color != color ) || forceit) { m_box_color = color;
// The DC for the color box CDC* pCOLORDC = GetDlgltem (IDCJCOLORBOX) ->GetDC 0 ; // pCOLORDC- >GetRect () ;
// Create a PEN
// CPen ♦pQPen = new CPen (PS_SOLID, 3 , RGB (0 , 0 , 255) ) ;
// CPen pOldPen = pXDC->SelectObject (pQPen) ;
// Create the Brush
CBrush ♦pQBrush = new CBrush (color) ,- 000329
// Select this brush, save the old
CBrush pOldBrush = pCOLORDC- >SelectObject (pQBrush) ,-
// Draw the box
// pCOLORDC- >Rectangle (CRect (1, 1, 65, 65) ) ; pCOLORDC- >Rectangle (m_colorJbox_rec) ; pCOLORDC- >SelectObj ect (ScpOldBrush) ; // Reset the brush delete (pQBrush) ; ReleaseDC (pCOLORDC) ;
// GetDlgltem (IDCJLOGO_Q) ->Invalidate 0 ; // GetDlgltem (IDC_INST) ->Invalidate ( ) ;
void COentryView: ^nDrawfCDC^ pDC)
/* pControlDC- >SelectStockObj ect (WHITE_BRUSH) ,- */
// The DC for the Instance name /*
CDC* pINSTDC = GetDlgltem ( IDCJINST) ->GetDC() ; pINSTDC- >SetBkColor (m_color) ; pINSTDC- >SetTextColor (m_color) ,- pINSTDC- >SetBkMode (TRANSPARENT) ; pINSTDC- >SelectStockObj ect (HOLLOW BRUSH) ; */
GetDlgltem (IDC_COLORBOX) ->GetWindowRect (Sem_color_box_rec) ; m_color_box_rec. right -= m_color_box_rec . left ,- //ScreenToClient (&rec) ,- m_color_box_rec .bottom -= m_color_box_rec . top; m_color_box_rec . left = m_color_box_rec . top = 0 ,- color_the_box(m_box_color, 1) ,- CFormView: :OnDraw(pDC) ;
/void COentryView: :OnResetb() m_mes_sent = 0 ,- m_mes_rec = 0 ,- m_rec_sent = 0 ,- m_rec_rec = 0 ,-
SetDlgltemlnt (IDC_MES_REC, 0) ,- SetDlgltemlnt (IDCJREC_REC, 0) ; SetDlgltemlnt (IDC_MES_SENT, 0) ,- SetDlgltemlnt (IDC_REC_SENT, 0) ;
OnAnyUserAction ( ) ;
// TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT // TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT void COentryView: :OnTranb () mjtran_state = 1; GetDlgltem (IDCJTRANB) ->ShowWindow (SWJHIDE) ; GetDlgltem (IDC_ABORTB) ->ShowWindow (SW_SHOW) ; GetDlgltem (IDCJ20MMITB) ->ShowWindow (SW_SHOW) ; OnAnyUserActionO ;
void COentryView: :OnCommit (int action)
// Anyway get rid of the commit/abort buttons GetDlgltem (IDCJTRANB) - >ShowWindow (SW_SHOW) ; GetDlgltem (IDCJABORTB) ->ShowWindow (SW_HIDE) ; GetDlgltem ( IDCJDOMMITB) ->ShowWindow (SW_HIDE) ;
// Do the commit if ( (Q) ScSc (m_tran_state > 1)) Qcommit (action) ,- m_tran_rec = 0 ; m_tran_sent = 0 ; m tran state = 0;
} ~ " void COentryView: :OnCommitb()
OnCommit (Q COMMIT) ; } void COentryView: :OnAbortb()
OnCommit (Q_ABORT) ; m_mes_sent -= m_tran_sent ; m rec rec -= m tran rec;
} " ~ " " void COentryView: :OnLButtonDown (UINT nFlags, CPoint point)
CRect rec; // WINDOWPLACEMENT GetWindowPlacement CRect // MessageBeep (0) ;
GetDlgltem (IDCJCOLORBOX) ->GetWindowRect (irec) ;
ScreenToClient (Scree) ; if (rec. PtlnRect (point) ) OnColorO;
CFormView: :OnLButtonDown (nFlags, point) ,- } void COentryView: : OnRButtonDown (UINT nFlags, CPoint point)
ClearDisplay () ;
CFormView: : OnRButtonDown (nFlags, point) ;
void COentryView : : ClearDisplay ( )
(
GetParentFrame ( ) - >SetMessageText ( " " ) ; this->Invalidate () ,- OnAnyUserActionO ;
void COentryView: :OnShowdb ()
(
GetDlgltem (IDCJ3HOWDB) ->EnableWindow (FALSE) ; SetTimer (DB_DONEJTIMER, 2000, NULL) ,- // When the DB is done re-enable // CDbDlg dbd; // dbd. DoModal () ; dbd . Create ( IDDJDBDLG) ;
//GetParentFrame 0 ->SetMessageText ( "After dbd. Create "); } void COentryView: :OnOptionsb()
GetDlgltem (IDCJDPTIONSB) ->EnableWindow (FALSE) ; SetTimer (OPTIONS_DONE_TIMER, 2000, NULL) ; // When the options are done re-enabl
// o_dlg. Create (IDDjDJDLG) ; if (o_dlg .m_inst != m_inst) { // Init o_dlg.m_inst = m_inst; // o_dlg .m_parentptr = this; o_dlg . Create ( IDDJDJDLG) ;
g_new_color = m_color; o_dlg.ShowWindow(SW_SHOW) ,-
}
DROP TABLE omq_stock; /
CREATE TABLE omq_stock
(item VARCHAR2(10) PRIMARY KEY, price NUMBER, qty NUMBER) ; /
INSERT INTO omq_stock VALUES (' Bolts ', 1 , 1000) ;
/
INSERT INTO omq_stock VALUES (' Buckets ', 2 , 1000)
/
INSERT INTO omq stock VALUES (' Buttons ', 3 , 1000)
/
INSERT INTO omq_stock VALUES (' Belts ', 4 , 1000 ) ;
/
INSERT INTO omq_stock VALUES (' Bobbins ', 5 , 1000)
/
INSERT INTO omq_stock VALUES (' Boats ', 6 , 1000) ;
/
COMMIT WORK; /
DROP TABLE omq_cust; /
CREATE TABLE omq_cust
(customer VARCHAR2(10) PRIMARY KEY, orders NUMBER, sales NUMBER) ;
/
INSERT INTO omq cust VALUES ' Jacobs ',0,0);
/
INSERT INTO omq cust VALUES ' Jackson ',0,0);
/
INSERT INTO omq cust VALUES ' Jaffe' ,0,0) ,-
/
INSERT INTO omq cust VALUES ' Johnson' ,0,0) ,-
/
INSERT INTO omq_cust VALUES ' Jones ' ,0,0) ,-
/
INSERT INTO omq cust VALUES 'James ',0,0);
/
COMMIT WORK; /
/♦ File name & Package Name / struct sqlcxp unsigned short fillen; char fιlnam[10],-
}; static struct sqlcxp sqlfpn =
9,
"oraomq .pc"
static const unsigned long sqlctx = 822081471;
static struct sqlexd { unsigned long sqlvsn; unsigned long arrsiz ; unsigned long iters ,- unsigned short offset; unsigned short selerr; unsigned short sqlety; unsigned short unused; short cud; unsigned char ♦sqlest ,- char stmt; unsigned char ♦ ♦sqphsv, unsigned long sqphsl ; short * ♦sqpmd; unsigned long ♦sqparm; unsigned long * ♦sqparc ; unsigned char ♦sqhstv [ 3 ] ,- unsigned long sqhst l [3 ] ; short ♦ sqmdv [3 ] ,- unsigned long sqharm [ 3 ] ; unsigned long ♦sqharc [3 ] ; } sqlst = {8,3},- extern sqlcx2 (/♦ unsigned long struct sqlexd struct sqlcxp _/) ; extern sqlctet/^ unsigned long struct sqlexd struct sqlcxp ♦ ♦/) ; extern sqlbuf (/ char ♦ ♦/) ; extern sqlora(/^_ unsigned long , void _*/) ; static t IAPSUCC = 0; static t IAPFAIL = 1403; static t IAPFTL = 535; extern sqliemO ;
/ cud (compilation unit data) array / static short sqlcud0[] =
(8,34,
2, 0,8, 0,0, 0,0, 0,0, 0,0, 0,0, 0,27, 88, 0,3, 3, 0,1, 0,1, 9, 0,0,1, 10, 0,0,1, 10, 0,0,
36,0,8,0,0,0,0,0,0,0,0,0,0,0,30,111,0,0,0,0,1,0,
58,0,8,0,0,0,0,0,0,0,0,1,20,0,1,151,0,0,0,0,1,0,
80,0,8,0,0,0,0,0,0,0,0,2,19,0,1,152,0,0,0,0,1,0,
102,0,8,0,0,0,0,0,0,0,0,3,76,0,44,157,0,0,0,0,1,0,
124,0,8,0,0,0,0,0,0,0,0,4,45,0,3,161,0,0,0,0,1,0,
146,0,8,0,0,0,0,0,0,0,0,5,47,0,3,162,0,0,0,0,1,0,
168, 0,8, 0,0, 0,0, 0,0, 0,0, 6, 47, 0,3, 163, 0,0, 0,0, 1,0,
190, 0,8, 0,0, 0,0, 0,0, 0,0, 7, 45, 0,3, 164, 0,0, 0,0, 1,0,
212, 0,8, 0,0, 0,0, 0,0, 0,0, 8, 47, 0,3, 165, 0,0, 0,0, 1,0,
234, 0,8, 0,0, 0,0, 0,0, 0,0, 9, 45, 0,3, 166, 0,0, 0,0, 1,0,
256, 0,8, 0,0, 0,0, 0,0, 0,0, 10, 82, 0,44, 168, 0,0, 0,0, 1,0,
278, 0,8, 0,0, 0,0, 0,0, 0,0, 11, 41, 0,3, 172, 0,0, 0,0, 1,0,
300, 0,8, 0,0, 0,0, 0,0, 0,0, 12, 42, 0,3, 173, 0,0, 0,0, 1,0,
322, 0,8, 0,0, 0,0, 0,0, 0,0, 13, 40, 0,3, 174,0, 0,0,0,1,0,
344, 0,8, 0,0, 0,0, 0,0, 0,0, 14, 42, 0,3, 175, 0,0, 0,0, 1,0,
366, 0,8, 0,0, 0,0, 0,0, 0,0, 15, 40, 0,3, 176, 0,0, 0,0, 1,0,
388, 0,8, 0,0, 0,0, 0,0, 0,0, 16, 40, 0,3, 177, 0,0, 0,0, 1,0,
410, 0,8, 0,0, 0,0, 0,0, 0,0, 16, 0,0, 29, 179, 0,0, 0,0, 1,0,
432, 0,8, 0,0, 0,0, 0,0, 0,0, 17, 58, 0,4, 211, 0,3, 1,0, 1,0, 1,9, 0,0, 2, 3, 0,0, 2, 3, 0,0,
466, 0,8, 0,0, 0,0, 0,0, 0,0, 18, 43, 0,5, 259, 0,2, 2, 0,1, 0,1, 3, 0,0, 1,9, 0,0,
496, 0,8, 0,0, 0,0, 0,0, 0,0, 18, 0,0, 29, 263, 0,0, 0,0, 1,0,
518, 0,8, 0,0, 0,0, 0,0, 0,0, 19, 64, 0,4, 306, 0,3, 1,0, 1,0, 1,9, 0,0, 2, 3, 0,0, 2, 3, 0,0,
552, 0,8, 0,0, 0,0, 0,0, 0,0, 20, 59, 0,5, 356, 0,3, 3, 0,1, 0,1, 3, 0,0, 1,3, 0,0, 1,9, 0,0,
586, 0,8, 0,0, 0,0, 0,0, 0,0, 20, 0,0, 9, 360, 0,0, 0,0, 1,0,
};
/* * *
♦♦ Copyright (C) 1996 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
♦♦ UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
♦♦ LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
♦♦ IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
♦♦ OR DISCLOSURE.
**
♦♦ THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
* TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
♦♦ OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
♦♦ OpenMQ Demo
♦♦ Module: oraomq.pc
♦♦ Author: Frederick J. Igo, Jr. 1/15/96
**
ttinclude <stdl ib . h> ttinclude <stdio . h> ttinclude <ctype . h> ttinclude <string . h> tt include " sqlproto . h "
# include " ociproto . h" a def ine ORACLE
H include " oraomq . h "
/ * SQL stmt tt l
EXEC SQL INCLUDE SQLCA. H;
/
/ Copyright (c) 1985,1986 by Oracle Corporation. /
/* NAME
SQLCA : SQL Communications Area. FUNCTION
Contains no code. Oracle fills in the SQLCA with status info during the execution of a SQL stmt. NOTES _
If the symbol SQLCA_STORAGE_CLASS is defined, then the SQLCA will be defined to have this storage class. For example ttdefme SQLCA_STORAGE_CLASS extern will define the SQLCA as an extern.
If the symbol SQLCAJINIT is defined, then the SQLCA will be statically initialized. Although this is not necessary in order to use the SQLCA, it is a good pgming practice not to have unitialized variables. However, some C compilers/OS's don't allow automatic variables to be init'd in this manner Therefore, if you are INCLUDE ' ing the SQLCA in a place where it would be an automatic AND your C compiler/OS doesn't allow this style of initialization, then SQLCA_INIT should be left undefined -- all others can define SQLCA_INIT if they wish
New rules for defining SQLCA_INIT, SQLCA_STORAGE_CLASS , and DLL m OS/2 Users should not define SQLCA_STORAGE_CLASS if defining DLL SQLCA_STORAGE_CLASS is primarily used for smgle-threaded programs and for internal development.
MODIFIED Okamura 08/15/89 - OS/2- users must define SQLMT for multi-threaded case Okamura 06/23/89 - OS/2: modify for multi -threaded case Clare 12/06/84 - Ch SQLCA to not be an extern. Clare 10/21/85 - Add initialization Bradbury 01/05/86 - Only initialize when SQLCA_INIT set Clare 06/12/86 - Add SQLCA_STORAGE_CLASS option
*/ ttifndef SQLCA ttdefine SQLCA 1 struct sqlca
/ ubl ♦/ char sqlcaid [8] /* b4 ♦/ long sqlabc ,
/ b4 ♦/ long sqlcode ,- struct
(
/ ub2 ♦/ unsigned short sqlerrml;
/ ubl / char sqlerrmc [70] ;
} sqlerrm, / ubl / char sqlerrp [8] , / b4 ♦/ long sqlerrd [6] , / ubl / char sqlwarn [8] ,- / ubl / char sqlext [8] ;
ttifdef SQLMT extern struct sqlca sqlcamtO; / For multi-threaded version ♦/ ^ define sqlca (sqlcamtO) ttelse / SQLMT / ttifdef SQLCA_STORAGE_CLASS
SQLCA_STORAGE_CLASS struct sqlca sqlca # fdef SQLCA_INIT
{ 'S' , 'Q' , 'L' , 'C , 'A' , ' ' , '
sizeof (struct sqlca),
# endif /
Figure imgf000339_0001
ttelse / SQLCA_STORAGE_CLASS / struct sqlca sqlca ' / For single-threaded version ♦/
# ifdef SQLCA INIT
= ( "
{ 'S' , 'Q' , 'L' , 'C , 'A' , ' ' , ' ' , ' ' }, sizeof (struct sqlca),
# endif
Figure imgf000339_0002
ttendif /♦ SQLCA_STORAGE_CLASS / ttendif / SQLMT */
/ end SQLCA / ttendif /♦ SQLCA ♦/
/ ttinclude <C : \ORANT\PR016\C\sqlca . h> ♦/
/* NAME oraomq FUNCTION
Openmq Oracle Pro^C subroutines NOTES oraerrrpt () ,- -- Prints SQL Errors msgs Sc codes oraconn ( ... ) ; -- CONNECTS to ORACLE using given oracle string. oradiscO; -- DISCONNECTS from ORACLE oracreateO; -- Creates omq_stock & omq_cust tables in ORACLE. oraread ( ... ) ; -- Given ITEM name, reads PRICE Sc QTY. orawrite ( ... ) -- Given ITEM name Sc QTY, updates QTY IN db . oracustr ( ... ) -- Given CUSTOMER name, reads ttORDERS Sc $SALES. oracust ( ... ) -- Given CUSTOMER name, ttORDERS Sc $SALES, updates db.
C:\ORANT\PR016\C> nmake -f oraomq. mak
/*
ORAERRRPT prints the ORACLE error msg and number.
oraerrrpt 0
{ printf ("% .70s (%d)\n", sqlca . sqlerrm. sqlerrmc, -sqlca . sqlcode) return (0) ;
ORACONN connects to ORACLE as user DEMO.
Oracle String is provided by caller as: "SCOTT/TIGER@T:GRAMPA:ORCL" returns 0 on success and 1 on SQL error.
oraconn (orastring) char orastring [80] ,-
( / SQL stmt #2
EXEC SQL BEGIN DECLARE SECTION; */ struct { unsigned short len; unsigned char arr[80] ; } oracleid; /*
VARCHAR oracleid [80] ;
/o username/passwordodbstring o/ EXEC SQL END DECLARE SECTION; */
/ SQL stmt #4
EXEC SQL WHENEVER SQLERROR GOTO errexit; */ strcpy ( (char *) oracleid . arr, orastring) ,- oracleid. len = strlendchar ) oracleid. arr) ;
/ SQL stmt #5
EXEC SQL CONNECT : oracleid; */
{ struct sqlexd sqlstm= { 8 , 3 } ; sqlstm.iters = (unsigned int )10; sqlstm.offset = (unsigned int )2; sqlstm.cud = sqlcudO; sqlst .sqlest = (unsigned char )Scsqlca; sqlstm.sqlety = (unsigned short) 0; sqlstm.sqhstv[0] = (unsigned char ) Seoracleid; sqlstm.sqhstl [0] = (unsigned int )82,- sqlstm. sqindv[0] = ( short )0; sqlstm. sqharm[0] = (unsigned int )0; sqlstm.sqphsv = sqlstm. sqhstv; sqlstm. sqphsl = sqlstm.sqhstl; sqlstm. sqpind = sqlstm. sqindv; sqlstm. sqparm = sqlstm. sqharm; sqlstm. sqparc = sqlstm. sqharc; nf f) QR sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ; if (sqlca . sqlcode < 0) goto errexit;
return (0) ;
/♦ Here if SQL Error / errexit : / SQL stmt #6
EXEC SQL WHENEVER SQLERROR CONTINUE;
*/ return (1) ;
/*
ORADISC disconnects from ORACLE, returns 0 on success and 1 on SQL error.
oradisc ( ) (
/ SQL stmt #7
EXEC SQL WHENEVER SQLERROR GOTO errexit,
* /
/ SQL stmt #8
EXEC SQL COMMIT RELEASE;
* / struct sqlexd sqlstm=( 8 , 0 } ; sqlstm. iters = (unsigned int )1; sqlstm. offset = (unsigned int )36; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char )Scsqlca; sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ; if (sqlca. sqlcode < 0) goto errexit;
return (0) ;
/ Here if SQL Error / errexit : / SQL stmt tt
EXEC SQL WHENEVER SQLERROR CONTINUE;
7 return (1) ;
n
ORACREATE creates omq_stock Sc omq_cust tables in ORACLE as follows:
omq_stock: ITEM PRICE QTY
Bolts $1 10000
Buckets $2 10000
Buttons $3 10000
Belts $4 10000
Bobbins $5 10000
Boats $6 10000 omq_cust : CUSTOMER ORDERS SALES
Jacobs 0
Jackson 0
Jaffe 0
Johnson 0
Jones 0
James 0 returns 0 on success and 1 on SQL error.
oracreate 0
/ Expect an error if table already dropped ♦/
SQL stmt #10
EXEC SQL WHENEVER SQLERROR GOTO ignore;
EXEC SQL DROP TABLE omq_stock;
struct sqlexd sqlstm= { 8 , 0 } ,- sqlstm. stmt = "DROP TABLE OMQ_STOCK" ; sqlstm. iters = (unsigned int ) 1 ,- sqlstm. offset = (unsigned int )58; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char )Scsqlca,- sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ; if (sqlca. sqlcode < 0) goto ignore;
SQL stmt #12
EXEC SQL DROP TABLE omq_cust;
struct sqlexd sqlstm={8, 0} ; sqlstm. stmt = "DROP TABLE OMQJCUST" ,- sqlstm. iters = (unsigned int ) 1 ; sqlstm. offset = (unsigned int )80; sqlstm. cud = sqlcudO; sqlstm . sqlest = (unsigned char ) Scsqlca ; sqlstm . sqlety = (unsigned short ) 0 ; sqlcex ( sqlctx , Scsqlstm, Sesqlfpn) ; if ( sqlca . sqlcode < 0 ) goto ignore ;
} ignore : / SQL stmt ttl3
EXEC SQL WHENEVER SQLERROR GOTO errexit ; */
/* SQL stmt #14
EXEC SQL CREATE TABLE omq_stock
(item VARCHAR2(10) PRIMARY KEY, price NUMBER, qty NUMBER) ; */ struct sqlexd sqlstm={ 8 , 0 } ; sqlstm. stmt = "CREATE TABLE OMQ_STOCK (ITEM VARCHAR2 (10) PRIMARY KEY, PRIC\ E NUMBER, QTY NUMBER)"; sqlstm. iters = (unsigned int )1; sqlstm. offset = (unsigned int )102; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char )Sesqlca; sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ,- if (sqlca . sqlcode < 0) goto errexit; }
/ SQL stmt #15
EXEC SQL INSERT INTO omq_stock VALUES (' Bolts ', 1 , 10000) ; */ struct sqlexd sqlstm= { 8 , 0 } ; sqlstm. stmt = "INSERT INTO OMQ_STOCK VALUES (' Bolts ', 1, 10000) " ; sqlstm. iters = (unsigned int ) 1 ,- sqlstm. offset = (unsigned int )124; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char )Scsqlca,- sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ,- if (sqlca . sqlcode < 0) goto errexit;
/♦ SQL stmt #16
EXEC SQL INSERT INTO omq_stock VALUES (' Buckets ', 2 , 10000) ;
* / struct sqlexd sqlstm= ( 8 , 0 } ; sqlstm. stmt = "INSERT INTO OMQ_STOCK VALUES (' Buckets ', 2 , 10000) " ; sqlstm. iters = (unsigned int ) 1 ; sqlstm. offset = (unsigned int )146; sqlstm. cud = sqlcudO; sqlstm . sqlest = (unsigned char ) Scsqlca ; sqlstm . sqlety = (unsigned short ) 0 ; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ; if ( sqlca . sqlcode < 0 ) goto errexit ;
/♦ SQL stmt #17
EXEC SQL INSERT INTO omq_stock VALUES (' Buttons ', 3 , 10000 ) ;
* / struct sqlexd sqlstm= ( 8 , 0 } ,- sqlstm. stmt = "INSERT INTO OMQ_STOCK VALUES (' Buttons ', 3 , 10000) " ; sqlstm. iters = (unsigned int ) 1 ; sqlstm. offset = (unsigned int )168; sqlstm. cud = sqlcudO; sqlstm . sqlest = (unsigned char ) ScSqlca ; sqlstm . sqlety = (unsigned short ) 0 ; sqlcex (sqlctx , Scsqlstm, Sesqlfpn) ; if ( sqlca . sqlcode < 0 ) goto errexit ; / SQL stmt #18
EXEC SQL INSERT INTO omq_stock VALUES (' Belts ', 4 , 10000) ; */ { struct sqlexd sqlstm= { 8 , 0 } ; sqlstm. stmt = "INSERT INTO OMQ_STOCK VALUES (' Belts ', 4 , 10000) " ; sqlstm. iters = (unsigned int )1; sqlstm. offset = (unsigned int )190; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char *)Scsqlca; sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ; if (sqlca . sqlcode < 0) goto errexit;
/ SQL stmt #19
EXEC SQL INSERT INTO omq_stock VALUES (' Bobbins ', 5 , 10000 ) ; */ { struct sqlexd sqlstm= { 8 , 0 } ,- sqlstm. stmt = "INSERT INTO OMQ_STOCK VALUES (' Bobbins ', 5 , 10000) " ; sqlstm. iters = (unsigned int ) 1 ,- sqlstm. offset = (unsigned int )212; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char *)Scsqlca,- sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ,- if (sqlca . sqlcode < 0) goto errexit;
/ SQL stmt #20
EXEC SQL INSERT INTO omq stock VALUES (' Boats ', 6 , 10000) ,- /
{ struct sqlexd sqlstm= { 8 , 0 } ,- sqlstm. stmt = "INSERT INTO OMQ_STOCK VALUES (' Boats ', 6 , 10000) " ; sqlstm. iters = (unsigned int )1; sqlstm. offset = (unsigned int )234; sqlstm. cud = sqlcudO; sqlstm . sqlest = (unsigned char ♦ ) Sesqlca ; sqlstm . sqlety = (unsigned short ) 0 ; sqlcex ( sqlctx, Scsqlstm, Sesqlfpn) ,- if ( sqlca . sqlcode < 0 ) goto errexit ;
/ SQL stmt #21
EXEC SQL CREATE TABLE omq_cust
(customer VARCHAR2(10) PRIMARY KEY, orders NUMBER, sales NUMBER) ;
*/ struct sqlexd sqlstm={ 8 , 0 } ; sqlstm. stmt = "CREATE TABLE OMQJCUST ( CUSTOMER VARCHAR2 (10) PRIMARY K\ EY, ORDERS NUMBER, SALES NUMBER)"; sqlstm. iters = (unsigned int ) 1 ; sqlstm. offset = (unsigned int )256; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char *)Scsqlca; sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ; if (sqlca. sqlcode < 0) goto errexit; 000 4 ? }
/ SQL stmt #22
EXEC SQL INSERT INTO omq_cust VALUES (' Jacobs ', 0 , 0 ) ; */ struct sqlexd sqlstm=(8, 0} ; sqlstm . stmt = " INSERT INTO OMQ_CUST VALUES ( ' Jacobs ',0,0)"; sqlstm. iters = (unsigned int ) 1 ; sqlstm. offset = (unsigned int )278; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char *)Sesqlca; sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ; if (sqlca. sqlcode < 0) goto errexit;
/ SQL stmt #23
EXEC SQL INSERT INTO omq_cust VALUES (' Jackson ' 0 0) - */ ( struct sqlexd sqlstm= { 8 , 0 } ; sqlstm. stmt = "INSERT INTO OMQ_CUST VALUES (' Jackson ', 0 , 0) " ; sqlstm. iters = (unsigned int ) 1 ; sqlstm. offset = (unsigned int )300; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char *)Sesqlca; sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ; if (sqlca . sqlcode < 0) goto errexit;
/ SQL stmt #24
EXEC SQL INSERT INTO omq_cust VALUES (' Jaffe ', 0 , 0) • */ { struct sqlexd sqlstm= { 8 , 0 } ,- sqlstm. stmt = "INSERT INTO OMQ_CUST VALUES (' Jaffe ', 0 , 0) " ; sqlstm. iters = (unsigned int ) 1 ; sqlstm. offset = (unsigned int )322; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char )Sesqlca; sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ; if (sqlca. sqlcode < 0) goto errexit;
/ SQL stmt #25
EXEC SQL INSERT INTO omq_cust VALUES (' Johnson ', 0 , 0) • */
{ struct sqlexd sqlstm= { 8 , 0 } ; sqlstm. stmt = "INSERT INTO OMQ_CUST VALUES (' Johnson ', 0 , 0 )" ; sqlstm. iters = (unsigned int ) 1 ; sqlstm. offset = (unsigned int )344; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char )Scsqlca; sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ; if (sqlca. sqlcode < 0) goto errexit;
/* SQL stmt #26
EXEC SQL INSERT INTO omq_cust VALUES (' Jones ', 0 , 0) ; */
struct sqlexd sqlstm= { 8 , 0 } ; sqlstm. stmt = "INSERT INTO OMQ_CUST VALUES (' Jones ', 0 , 0) " ; sqlstm. iters = (unsigned int )l; sqlstm. offset = (unsigned int )366; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char ♦JScsqlca; sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, ksqlfpn) ; if (sqlc . sqlcode < 0) goto errexit;
/* SQL stmt #27
EXEC SQL INSERT INTO omq_cust VALUES (' James ', 0 , 0) ; */ ( struct sqlexd sqlstm= ( 8 , 0 } ; sqlstm. stmt = "INSERT INTO OMQ_CUST VALUES (' James ', 0 , 0) " ,- sqlstm. iters = (unsigned int ) 1 ; sqlstm. offset = (unsigned int )388; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char )Scsqlca; sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ; if (sqlca . sqlcode < 0) goto errexit;
/ SQL stmt #28
EXEC SQL COMMIT WORK; */ ( struct sqlexd sqlstm= { 8 , 0 } ; sqlstm. iters = (unsigned int )1; sqlstm. offset =- (unsigned int )410; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char )Scsqlca; sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ; if (sqlca . sqlcode < 0) goto errexit;
return (0) ,-
/ Here if SQL Error / errexit : / SQL stmt #29
EXEC SQL WHENEVER SQLERROR CONTINUE; */ return (1) ,-
/*
ORAREAD reads QTY Sc PRICE from omq_stock table given ITEM, returns 0 on success, 1 on SQL error and 2 on noitem.
int orareaddtemname, itemprice, itemqty)r ) char itemname [10] ; int ♦itemprice, itemqty; / SQL stmt #30
EXEC SQL BEGIN DECLARE SECTION; */ struct ( unsigned short len; unsigned char arr [10],- } item; h
VARCHAR item [10] ;
/o item name o/
-I mt price; / item price ♦/ int qty; / item quantity ♦/ / SQL stmt #31
EXEC SQL END DECLARE SECTION; */
/♦ SQL stmt #32
EXEC SQL WHENEVER NOT FOUND GOTO noitem; EXEC SQL WHENEVER SQLERROR GOTO errexit;
"I strcpy ( (char ♦) item, arr, itemname) ,- item, len = strlen (itemname) ,-
SQL stmt #34
EXEC SQL SELECT PRICE, QTY
INTO :price, : qty FROM omq_stock WHERE ITEM = :item;
struct sqlexd sqlstm= { 8 , 3 } ; sqlstm. stmt = "SELECT PRICE, QTY INTO:bl,:b2 FROM OMQ_STOCK WHERE ITEM=:b3"; sqlstm. iters = (unsigned int ) 1 ,- sqlstm. offset = (unsigned int )432; sqlstm. selerr = (unsigned short) 1; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char )Scsqlca,- sqlstm. sqlet (unsigned short) 0; sqlstm. sqhstv [0] = (unsigned char ♦)Scitem; sqlstm.sqhstl [0] = (unsigned int )12,- sqlstm. sqindv [0] = ( short ♦)0; sqlstm. sqharm [0] = (unsigned int )0; sqlstm. sqhstv [1] (unsigned char Scprice ,- sqlstm.sqhstl [1] (unsigned int )4 sqlstm. sqindv [1] ( short 0 ; sqlstm. sqharm [1] (unsigned int ) 0 sqlstm. sqhstv [2] (unsigned char Scqty ; sqlstm.sqhstl [2] (unsigned int )4 sqlstm. sqindv [2] ( short ♦ 0 ; sqlstm. sqharm [2] (unsigned int ) 0 sqlstm. sqphsv = sqlstm. sqhstv; sqlstm. sqphsl = sqlstm.sqhstl; sqlstm. sqpind = sqlstm. sqindv,- sqlstm. sqparm = sqlstm. sqharm; sqlstm. sqparc = sqlstm. sqharc; sqlcex ( sqlctx , Scsqlstm, Sesqlfpn) ,- i f (sqlca sqlcode == 1403 ) goto noitem, if ( sqlca sqlcode < 0 ) goto errexit ,
/♦ SQL stmt #35
EXEC SQL WHENEVER NOT FOUND STOP, EXEC SQL WHENEVER SQLERROR CONTINUE,
*/
itemprice = price, itemqty = qty, return (0) ,
/* Here if item NOT found dbs / noitem /* SQL stmt #37
EXEC SQL WHENEVER NOT FOUND STOP, EXEC SQL WHENEVER SQLERROR CONTINUE,
*/ return (2) ,
/* Here if SQL Error ♦/ errexit /♦ SQL stmt #39
EXEC SQL WHENEVER NOT FOUND STOP, EXEC SQL WHENEVER SQLERROR CONTINUE,
*/ return (1) ,
/*
ORAWRITE updates QTY for a given ITEM the omq_stock table returns 0 on success, 1 on SQL error and 2 on noitem
int orawπte (itemname, itemqty) char itemname [10] , mt itemqty,
/ SQL stmt #41
EXEC SQL BEGIN DECLARE SECTION, */ struct ( unsigned short len, unsigned char arr [10], } item, /*
VARCHAR item [10] ,
/o item name o/
*/ int qty, /* item quantity */
/ SQL stmt tt42
EXEC SQL END DECLARE SECTION, */
/ SQL stmt tt43 000346
EXEC SQL WHENEVER NOT FOUND GOTO noitem, EXEC SQL WHENEVER SQLERROR GOTO errexit, / strcpy((char *) item arr , itemname) , item len = strlen (itemname) , qty = itemqty,
/* SQL stmt #45
EXEC SQL UPDATE otnq_stock SET QTY = qty WHERE ITEM = item,
'/ struct sqlexd sqlstm= { 8 , 2 } , sqlstm stmt = "UPDATE OMQJSTOCK SET QTY= bl WHERE ITEM= b2 ' sqlstm iters = (unsigned mt )1, sqlstm offset = (unsigned int )466, sqlstm cud = sqlcudO, sqlstm sqlest = (unsigned char JScsqlca sqlstm sqlety = (unsigned short) 0, sqlstm sqhst [0] = (unsigned char J&qty, sqlstm sqhstl[0] = (unsigned int )4, sqlstm sqmdvio] = ( short * ) 0 , sqlstm sqharm [0] = (unsigned int )0, sqlstm sqhstv [1] = (unsigned char )Scitem, sqlstm sqhstl [1] = (unsigned mt )12, sqlstm sqindv [1] = ( short *)0, sqlstm sqharm [1] = (unsigned mt )0, sqlstm sqphsv = sqlstm sqhstv, sqlstm sqphsl = sqlstm sqhstl, sqlstm sqpind = sqlstm sqindv, sqlstm sqparm = sqlstm sqharm, sqlstm sqparc = sqlstm sqharc, sqlcex (sqlctx, Scsqlstm, Sesqlfpn) , if (sqlca sqlcode == 1403) goto noitem, if (sqlca sqlcode < 0) goto errexit,
}
/ SQL stmt #46
EXEC SQL COMMIT WORK, */ struct sqlexd sqlstm= { 8 , 0 } , sqlstm iters = (unsigned mt )1, sqlstm offset = (unsigned int )496, sqlstm cud = sqlcudO, sqlstm sqlest = (unsigned char )Scsqlca, sqlstm sqlety = (unsigned short) 0, sqlcex (sqlctx, Scsqlstm, Sesqlfpn) , if (sqlca sqlcode < 0) goto errexit,
/ SQL stmt #47
EXEC SQL WHENEVER NOT FOUND STOP, EXEC SQL WHENEVER SQLERROR CONTINUE,
' / return ( 0 ) ,
/♦ Here if item NOT found in dbs / noitem: / SQL stmt #49
EXEC SQL WHENEVER NOT FOUND STOP; EXEC SQL WHENEVER SQLERROR CONTINUE; k/ return (2)
/♦ Here if SQL Error / errexit : / SQL stmt #51
EXEC SQL WHENEVER NOT FOUND STOP; EXEC SQL WHENEVER SQLERROR CONTINUE;
*/ return (1) ;
ORACUSTR reads ORDERS & SALES from omq_cust table given customer name, returns 0 on success, 1 on SQL error and 2 on nocustomer.
int oracustr (custname , custorders, custsales) char custname [10] ; int ♦custorders, *custsales;
(
/ SQL stmt #53
EXEC SQL BEGIN DECLARE SECTION; */ struct { unsigned short len; unsigned char arr [10]; } customer; n
VARCHAR customer [10] ;
/o cust name o/ k/ int orders; / cust ttorders ♦/ int sales; / cust $sales / / SQL stmt #54
EXEC SQL END DECLARE SECTION; */
/ SQL stmt #55
EXEC SQL WHENEVER NOT FOUND GOTO noitem; EXEC SQL WHENEVER SQLERROR GOTO errexit,-
'/ strcpy ( (char *) customer . arr , custname) ; customer. len = strlen (custname) ;
/* SQL stmt #57
EXEC SQL SELECT ORDERS, SALES
INTO : orders, : sales
FROM omq__cust
WHERE CUSTOMER = : customer;
</ struct sqlexd sqlstm= { 8 , 3 } , sqlstm. stmt = "SELECT ORDERS, SALES INTO:bl, .b2 FROM OMQ_CUST WHERE CUSTOM\ ER= : b3 " ; sqlstm. iters = (unsigned mt )1; sqlstm. offset = (unsigned mt )518, sqlstm. selerr = (unsigned short) 1; sqlstm cud = sqlcudO, sqlstm. sqlest = (unsigned char )&sqlca, sqlstm. sqlety = (unsigned short) 0, sqlstm. sqhstv [0] unsigned char ) Sccustome , sqlstm sσnstl[0] unsigned mt )12, sqlstm. sqindv [0] short O, sqlstm. sqnarm [0] unsigned mt ) 0 , sqlstm sqhstv [1] unsigned char JScorders, sqlstm.sqhstl [1] unsigned int )4, sqlstm. sqindv [l] short )0; sqlstm. sqharm [1] unsigned mt ) 0, sqlstm. sqhstv [2] unsigned char *)£csales, sqlstm.sqhstl [2] unsigned int )4; sqlstm. sqindv [2] short * ) 0 ; sqlstm sqharm [2] unsigned mt ) 0 ; sqlstm sqphsv = sqlstm sqhstv, sqlstm sqphsl = sqlstm sqhstl, sqlstm sqpmd = sqlstm. sqindv, sqlstm sqparm = sqlstm sqharm, sqlstm. sqparc = sqlstm sqharc, sqlcex(sqlctx Scsqlstm, Sesqlfpn) , if (sqlca sqlcode 1403) goto noitem; if (sqlca sqlcode 0) goto errexit,
SQL stmt #58
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER SQLERROR CONTINUE;
custorders = orders; custsales = sales, return (0) ,
/ Here if item NOT found in dbs / noitem:
SQL stmt #60
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER SQLERROR CONTINUE; return (2) ,
/ Here if SQL Error / errexit
SQL stmt #62
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER SQLERROR CONTINUE; return ( 1 ) ;
/*
ORACUSTW updates ORDERS & SALES for a given CUSTOMER in the DB . returns 0 on success, 1 on SQL error and 2 on nocustomer.
int oracustw (custname, custorders, custsales) char custname [10] ,- int custorders, custsales;
{ / SQL stmt #64
EXEC SQL BEGIN DECLARE SECTION; */ struct ( unsigned short len; unsigned char arr [10]; } customer; /*
VARCHAR customer [10] ;
/o cust name o/ */ int orders; /* cust #orders ♦/ int sales; /* cust $sales ♦/
/ SQL stmt #65
EXEC SQL END DECLARE SECTION; */
/ SQL stmt #66
EXEC SQL WHENEVER NOT FOUND GOTO noi em; EXEC SQL WHENEVER SQLERROR GOTO errexit;
* / strcpy ((char *) customer .arr, custname) ,- customer. len = strlen (custname) ; orders = custorders; sales = custsales;
SQL stmt #68
EXEC SQL UPDATE omq_cust
SET ORDERS = : orders, SALES = .-sales
WHERE CUSTOMER = : customer;
*/ { struct sqlexd sqlstm= ( 8 , 3 } ; sqlstm. stmt = "UPDATE OMQ_CUST SET ORDERS= :bl , SALES= :b2 WHERE CUSTOMER=:b\ sqlstm. iters = (unsigned int )1; sqlstm. offset = (unsigned int )552; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char *)Scsqlca,- sqlstm. sqlety = (unsigned short) 0; sqlstm. sqhstv [0] = (unsigned char *)Scorders; sqlstm.sqhstl [0] = (unsigned int ) 4 ; sqlstm. sqindv [0] = ( short *)0; sqlstm. sqharm [0] = (unsigned int ) 0 ,- sqlstm. sqhstv [1] = (unsigned char )Sesales; sqlstm.sqhstl [1] = (unsigned int ) 4 ; sqlstm. sqindv [1] = ( short )0;
sqlstm. sqharm [1] = (unsigned int ) 0 ,- sqlstm. sqhstv [2] = (unsigned char ♦) Sccustomer; sqlstm. sqhstl [2] = (unsigned int )12; sqlstm. sqindv [2] = ( short ♦)0; sqlstm. sqharm [2] = (unsigned int ) 0 ,- sqlstm. sqphsv = sqlstm. sqhstv; sqlstm. sqphsl = sqlstm.sqhstl; sqlstm. sqpind = sqlstm. sqindv; sqlstm. sqparm = sqlstm. sqharm; sqlstm. sqparc = sqlstm. sqharc ; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ; if (sqlca. sqlcode == 1403) goto noitem; if (sqlca . sqlcode < 0) goto errexit;
SQL stmt #69
EXEC SQL COMMIT WORK;
struct sqlexd sqlstm= { 8 , 0 } ; sqlstm. iters = (unsigned int ) 1 ; sqlstm. offset = (unsigned int )586; sqlstm. cud = sqlcudO; sqlstm. sqlest = (unsigned char ♦)Scsqlca; sqlstm. sqlety = (unsigned short) 0; sqlcex (sqlctx, Scsqlstm, Sesqlfpn) ; if (sqlca . sqlcode < 0) goto errexit;
SQL stmt #70
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER SQLERROR CONTINUE;
return (0) ,-
/ Here if item NOT found in dbs ♦/ noitem:
SQL stmt #72
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER SQLERROR CONTINUE; return (2) ;
/ Here if SQL Error / errexit : SQL stmt #74
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER SQLERROR CONTINUE;
/ return ( 1 ) ,- /*
**
** Copyright (C) 1996 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED. ** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT ** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE ** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION ** OR DISCLOSURE. ** ** THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND ** TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE, ** OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR ** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA. ** ** OpenMQ Demo ** Module : oraomq . h
* * Author : Derek Schwenke 1/11/ 96
* *
*/
ttifdef CPP extern "C"
{ ttendif
ttifdef ORACLE int orawrite ( char itemname [10] , int itemqty) ; int oraread ( char itemname [10] , int itemprice, int ♦itemqty) ,- int oracustw ( char custname [10] , int custorders, int custsales); int oracustr ( char custname [10] , int custorders, int ♦custsales); int oradisc 0 ,- int oraconn ( char orastring [80] ) ; int oracreate 0 ; int oraerrrpt () ,- ttelse int orawrite ( char itemname [10] , int itemqty) int oraread ( char itemname [10] , int itemprice, int itemqty) int oracustw ( char custname [10] , int custorders, int custsales) int oracustr ( char custname [10] , int custorders, int ♦custsales) int oradisc () int oraconn ( char orastring [80] ) int oracreate () int oraerrrpt ( ) ttendif
ttifdef CPP
} ttendif /* **
** Copyright (C) 1996 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
** OR DISCLOSURE.
**
** THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
* * TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
** OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
** OpenMQ Demo
** Module: oraomq. pc
** Author: Frederick J. Igo, Jr. 1/15/96
**
*/
ttinclude <stdlib.h> ttinclude <stdio.h> ttinclude <ctype.h> ttinclude <string.h>
# include "sqlproto.h" ϋ include "ociproto.h"
# define ORACLE
# include "oraomq. h"
EXEC SQL INCLUDE SQLCA. H; / ttinclude <C: \ORANT\PR016\C\sqlca .h> ♦/
/* NAME oraomq FUNCTION
Openmq Oracle Pro^C subroutines NOTES oraerrrpt ( ) ; Prints SQL Errors msgs Sc codes oraconn (...); CONNECTS to ORACLE using given oracle string. oradisc 0 ; DISCONNECTS from ORACLE oracreate () ,- Creates omq_stock Sc omq_cust tables in ORACLE. oraread (...),- Given ITEM name, reads PRICE Sc QTY. orawrite (...) Given ITEM name Sc QTY, updates QTY IN db . oracustr ( ... ) Given CUSTOMER name, reads ttORDERS & $SALES. oracustw ( ... ) Given CUSTOMER name, ttORDERS Sc $SALES, updates db.
C:\ORANT\PR016\C> nmake -f oraomq. mak
ORAERRRPT prints the ORACLE error msg and number.
oraerrrpt ( )
printf ( " % . 70s ( %d) \n" , sqlca . sqlerrm . sqlerrmc , -sqlca . sqlcode ) , • return ( 0 ) ;
}
/*
ORACONN connects to ORACLE as user DEMO.
Oracle String is provided by caller as: "SCOTT/TIGER@T:GRAMPA:ORCL" . returns 0 on success and 1 on SQL error. */ oraconn (orastring) char orastring [80] ;
{
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR oracleid [80] ; / username/passwordodbstring ♦/
EXEC SQL END DECLARE SECTION;
EXEC SQL WHENEVER SQLERROR GOTO errexit; strcpy ( (char ♦ ) oracleid. arr, orastring) ; oracleid. len = strlen ((char *) oracleid . arr) ;
EXEC SQL CONNECT : oracleid; return (0) ,-
/ Here if SQL Error / errexit :
EXEC SQL WHENEVER SQLERROR CONTINUE; return (1) ; }
/*
ORADISC disconnects from ORACLE, returns 0 on success and 1 on SQL error.
oradisc () (
EXEC SQL WHENEVER SQLERROR GOTO errexit;
EXEC SQL COMMIT RELEASE; return (0) ;
/ Here if SQL Error / errexit :
EXEC SQL WHENEVER SQLERROR CONTINUE; return (1) ,-
ORACREATE creates omq_stock Sc omq_cust tables in ORACLE as follows: omq_stock : ITEM PRICE QTY
Bolts $1 10000
Buckets $2 10000
Buttons $3 10000
Belts $4 10000
Bobbins $5 10000
Boats $6 10000 omq cust : CUSTOMER ORDERS SALES
Jacobs 0
Jackson 0
Jaffe 0
Johnson 0
Jones 0
James 0 returns 0 on success and 1 on SQL error.
oracreate ( ) (
/ Expect an error if table already dropped / EXEC SQL WHENEVER SQLERROR GOTO ignore; EXEC SQL DROP TABLE omq_stock; EXEC SQL DROP TABLE omq_cust; ignore :
EXEC SQL WHENEVER SQLERROR GOTO errexit;
EXEC SQL CREATE TABLE omq_stock
(item VARCHAR2(10) PRIMARY KEY, price NUMBER, qty NUMBER) ;
EXEC SQL INSERT INTO omq_stock VALUES 0 Bolts ', 1 , 10000 ); EXEC SQL INSERT INTO omq_stock VALUES (' Buckets ', 2 ,10000) ; EXEC SQL INSERT INTO omq_stock VALUES ( ' Buttons , 3 ,10000) ; EXEC SQL INSERT INTO omq_stock VALUES (' Belts ', 4 , 10000) ; EXEC SQL INSERT INTO omq_stock VALUES ( ' Bobbins ' , 5 ,10000) ; EXEC SQL INSERT INTO omq_stock VALUES (' Boats ', 6 , 10000) ;
EXEC SQL CREATE TABLE omq_cust
(customer VARCHAR2(10) PRIMARY KEY, orders NUMBER, sales NUMBER) ;
EXEC SQL INSERT INTO omq_cust VALUES ( Jacobs ',0,0); EXEC SQL INSERT INTO omq_cust VALUES ( Jackson ' ,0,0) EXEC SQL INSERT INTO omq_cust VALUES ( 'Jaffe' ,0,0) ; EXEC SQL INSERT INTO omq_cust VALUES ( ' Johnson ',0,0) EXEC SQL INSERT INTO omq_cust VALUES ( Jones' ,0,0) ; EXEC SQL INSERT INTO omq_cust VALUES (' ames ', 0 , 0)
EXEC SQL COMMIT WORK;
return (0) ,-
/♦ Here if SQL Error / errexit :
EXEC SQL WHENEVER SQLERROR CONTINUE ; return (1) ; }
/*
ORAREAD reads QTY Sc PRICE from omq_stock table given ITEM, returns 0 on success, 1 on SQL error and 2 on noitem.
int oraread (itemname, itemprice, itemqty) char itemname [10] ; int ♦itemprice, itemqty;
(
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR item [10]; /♦ item name ♦/ int price; / item price ♦/ int qty; / item quantity ♦/ EXEC SQL END DECLARE SECTION;
EXEC SQL WHENEVER NOT FOUND GOTO noitem; EXEC SQL WHENEVER SQLERROR GOTO errexit; strcpy ( (char ♦) item, arr, itemname) ,- item, len = strlen (itemname) ,-
EXEC SQL SELECT PRICE, QTY
INTO : price, : qty FROM omq_stock WHERE ITEM = :item;
EXEC SQL WHENEVER NOT FOUND STOP; EXEC SQL WHENEVER SQLERROR CONTINUE;
*itemprice = price; itemqty = qty; return (0) ,-
/ Here if item NOT found in dbs / noitem:
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER SQLERROR CONTINUE; return (2) ;
/ Here if SQL Error / errexit :
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER SQLERROR CONTINUE; return (1) ,-
/*
ORAWRITE updates QTY for a given ITEM in the omq_stock table . returns 0 on success, 1 on SQL error and 2 on noitem.
int orawrite ( itemname , itemqty) char itemname [ 10] ; int itemqty;
(
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR item [10] ; / item name ♦/ int qty; / item quantity / EXEC SQL END DECLARE SECTION;
EXEC SQL WHENEVER NOT FOUND GOTO noitem; EXEC SQL WHENEVER SQLERROR GOTO errexit; strcpy ( (char ) item, arr, itemname) ,- item, len = strlen (itemname) ,- qty = itemqty;
EXEC SQL UPDATE omq_stock SET QTY = :qty WHERE ITEM = dtern;
EXEC SQL COMMIT WORK;
EXEC SQL WHENEVER NOT FOUND STOP; EXEC SQL WHENEVER SQLERROR CONTINUE; return (0) ;
/* Here if item NOT found in dbs / noitem:
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER SQLERROR CONTINUE; return (2 ) ,-
/* Here if SQL Error / errexit :
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER SQLERROR CONTINUE; return (1) ,- }
ORACUSTR reads ORDERS Sc SALES from omq_cust table given customer name, returns 0 on success, 1 on SQL error and 2 on nocustomer.
int oracustr (custname, custorders, custsales) char custname [10] ; int ♦custorders, custsales,-
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR customer [10] ; / cust name / int orders ,- / cust ttorders / int sales; / cust $sales / EXEC SQL END DECLARE SECTION;
EXEC SQL WHENEVER NOT FOUND GOTO noitem;
EXEC SQL WHENEVER SQLERROR GOTO errexit; strcpy ( (char ♦) customer .arr, custname) ,- customer. len = strlen (custname) ;
EXEC SQL SELECT ORDERS, SALES
INTO : orders, : sales
FROM omq_cust
WHERE CUSTOMER = : customer;
EXEC SQL WHENEVER NOT FOUND STOP; EXEC SQL WHENEVER SQLERROR CONTINUE;
custorders = orders; ♦custsales = sales; return (0) ,-
/* Here if item NOT found in dbs / noitem:
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER SQLERROR CONTINUE; return (2) ,-
/ Here if SQL Error / errexit :
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER SQLERROR CONTINUE; return (1) ,-
/*
ORACUSTW updates ORDERS Sc SALES for a given CUSTOMER in the DB . returns 0 on success, 1 on SQL error and 2 on nocustomer.
int oracustw (custname, custorders, custsales) char custname [10] ; int custorders, custsales;
{
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR customer [10] ; / cust name / int orders; / cust ttorders */ int sales; / cust $sales
EXEC SQL END DECLARE SECTION;
EXEC SQL WHENEVER NOT FOUND GOTO noitem; EXEC SQL WHENEVER SQLERROR GOTO errexit; strcpy ( (char ♦) customer . arr, custname) ; customer. len = strlen (custname) ; orders = custorders ; sales = custsales;
EXEC SQL UPDATE omq_cust
SET ORDERS = : orders, SALES = : sales WHERE CUSTOMER = : customer;
EXEC SQL COMMIT WORK;
EXEC SQL WHENEVER NOT FOUND STOP ; EXEC SQL WHENEVER SQLERROR CONTINUE ; return ( 0 ) ;
/* Here if item NOT found in dbs */ noitem:
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER SQLERROR CONTINUE; return (2) ,-
/* Here if SQL Error */ errexit :
EXEC SQL WHENEVER NOT FOUND STOP;
EXEC SQL WHENEVER SQLERROR CONTINUE; return ( 1 ) ; }
/♦ File name Sc Package Name ♦ / struct sqlcxp unsigned short fillen; char f ilnam [ll ] ; static struct sqlcxp sqlfpn =
(
10 ,
" oratest . pc "
static const unsigned long sqlctx = 822081478;
static struct sqlexd unsigned long sqlvsn; unsigned long arrsiz ,- unsigned long iters ,- unsigned short offset ; unsigned short selerr ; unsigned short sqlety; unsigned short unused; short cud ,- unsigned char ♦sqlest; char stmt; unsigned char ♦ ♦sqphsv; unsigned long sqphsl ; short * ♦sqpind; unsigned long ♦sqparm; unsigned long ♦ ♦sqparc; unsigned char ♦sqhstv [1] ,- unsigned long sqhstl [1] ; short ♦sqindv [1] ; unsigned long sqharm [1] ; unsigned long ♦sqharc [1] ,-
} sqlstm = (8,l}; extern sqlcx2(/*_ unsigned long , struct sqlexd *, struct sqlcxp */); extern sqlcte(/+ unsigned long , struct sqlexd , struct sqlcxp _*/) ; extern sqlbuf(/+_ char _*/) ; extern sqlora(/+_ unsigned long * , void _/) ; static int IAPSUCC = 0 ; static int IAPFAIL = 1403; static int IAPFTL = 535; extern sqliemO;
/* cud (compilation unit data) array */ static short sqlcudO [] =
(8,34,
/* **
Copyright (C) 1996 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED. UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION OR DISCLOSURE.
**
** THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND ** TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE, ** OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* * EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA. ** ** OpenMQ Demo ** Module: oratest.pc ** Author: Frederick J. Igo, Jr. 1/15/96 **
*/ ttinclude <stdlib.h> ttinclude <stdio.h> ttinclude <ctype.h> ttinclude <string.h>
# include "sqlproto.h" H include "ociproto.h"
# define ORACLE tt include "oraomq. h"
/* NAME openmq FUNCTION
Simple openmq Pro*C sample program NOTES openmq is a simple example program which decrements the stock for ordered items. Checking is done for sufficient stock .
The program queries the user for data as follows:
Enter customer name : Enter item name: Enter quantity ordered:
The program terminates if null string (<return> key) is entered when the customer name is requested.
If the item qty is updated, the following is printed:
"Order for QTY ITEM at PRICE has been placed"
C:\0RANT\PR016\C> nmake -f openmq.mak
OWNER
Igo DATE
01/11/96 MODIFIED igo 01/11/96 - create from sample32.pc */
void main () char itemname [10] ; /* item name ♦/ int itemprice; /* item price ♦/ int itemqty; /* item quantity ♦/ char custname [10] ; /* cust name ♦/ int custorders; /* cust ttorders ♦/ int custsales; /* cust $sales ♦/ char orastring [80] ,- /* Oracle ID ♦/ char orastrinp [80] ; /* Oracle ID ♦/
logon to ORACLE, and open the cursors. The program exits if any errors occur.
strcpy( (char ♦)orastring, "SCOTT/TIGER@T : GRAMPA : ORCL" ) ,- if (asks ("\nAlter connect string? (null keeps SCOTT/TIGER@T: ORACLE:ORCL) (char ♦) orastrinp) > 0 ) { strcpy((char ♦) orastring, (char ) orastrinp) ;
printf ( "\nConnecting to Oracle using string %s ...", orastring) ; if (oraconn (orastring) == 1) ( oraerrrpt ( ) ,- printf ("SQL Error on CONNECT, Bye-bye."),- return;
} printf ( "connected. \n" ) ,-
/* Create/Fill DB */ if ( asks ( "\nShall we create/clear the DB (non-null to create)?", (char *) custname) > 0 ) { printf ("Creating omq_stock and omq_cust tables in Oracle ... \n" ) ; if (oracreate 0 == 1) ( oraerrrpt 0 ; printf ("SQL Error on CREATE, Bye-bye.") ,- return; }
Read the user's input from STDIN. If the item name is not entered, exit. Verify that the entered quantity is lessthan that item's stock.
for( ,- ,- )
( int l,tot,qtyo;
/♦ Get customer name /
1 = asks ("\nEnter customer name (null to quit) (char ) custname) if ( 1 <= 0 ) break,- printf (" Checking Customer %s in DB... ", custname); switch (oracustr (custname, Sccustorders, Sccustsales) ) { case 1 : (
0003R2
oraerrrpt ( ) , printf ("SQL Error on Customer DB Read, try again \n") continue , case 2 ( printf ("No such customer, try again \n"), continue,
/♦ Get item name to be ordered ♦/ asks ( ' \nEnter item name ", (char ♦) itemname),
/ Read DB with given item name to get qty and price ♦/ printf (" Checking item m DB "), switch (oraread (itemname, Scitemprice, Scitemqty) ) { case 1 ( oraerrrpt ( ) , printf ("SQL Error on Customer DB Read, try again \n" continue , case 2 { printf ("No such item, try again \n"), continue ,
askn ( "\nEnter quantity ordered ",&qtyo), printf ( " Checking stock for %d %s ", qtyo, itemname) , if (qtyo > itemqty)
( printf (" Insufficient stock %d \n" , itemqty) , continue,
/ Here if item was found m dbs and quantity suffucient ♦/ itemqty -= qtyo, tot = qtyo ♦ itemprice,
/ Update DB for given item name / printf ("Updating %s QTY m Stock DB \n" , itemname) , switch (orawrite (itemname, itemqty) ) ( case 0 { prmtf ("\nOrder for %d %s at $%d each placed, ", qtyo, itemname, itemprice) , printf ("Sale is $%d, %d %s remain \n", tot , itemqty, itemname) , break,
} case 1 { oraerrrpt ( ) , printf ("SQL Error during DB update, order not placed \n") break,
} case 2 {
/♦ Shouldn't get this case, since read found item ♦/ printf ("No such item on write, please start over \n"),
/* Update Cust DB / custorders += 1; custsales += tot; switch (oracustw (custname, custorders, custsales) ) { case 0 : ( printf ("%s has placed %d orders for $%d.\n", custname, custorders, custsales) ; break; case 1 : { oraerrrpt ( ) ; printf ("SQL Error during cust DB update . \n" ) ; break; case 2 : {
/* Shouldn't get this case, since read found item ♦/ printf ("No such customer on write, please start over\n"); break;
) '
printf ==\n") ,- printf 'ITEM PRICE QTY\n") ; strcpy (char ) itemname, "Bolts" ) ; orareai ( itemname , Seitemprice , Scitemqty) ; printf "Bolts $%d %d\n" , itemprice, itemqty) ,- strcpy (char ♦) itemname, "Buckets" ) ,- oraread (itemname, Seitemprice, Scitemqty) ,- printf "Buckets $%d %d\n" , itemprice, itemqty) ,- strcpy (char ♦) itemname, "Buttons") ; oraread (itemname, Seitemprice, Scitemqty) ; printf "Buttons $%d %d\n" , itemprice, itemqty) ,- strcpy (char ♦) itemname, "Belts") ,- oraread (itemname, Sitemprice, Scitemqty) ,- printf "Belts $%d %d\n" , itemprice, itemqty) ; strcpy (char ♦) itemname, "Bobbins") ; oraread ( itemname , Seitemprice , Scitemqty) ; printf "Bobbins $%d %d\n" , itemprice, itemqty) ,- strcpy (char ♦) itemname, "Boats") ; orareai (itemname, Seitemprice, Scitemqty) ; printf "Boats $%d %d\n" , itemprice, itemqty) ,-
printf =======\n") ; printf "CUSTOMER ORDERS SALES\n") ; strcpy ( (char ♦) custname, "Jacobs") ;
oracustr (custname, Sccustorders , Sccustsales) ; printf ("Jacobs %d $ d\n" , custorders , custsales) ,- strcpy ( (char (custname, "Jackson") ; oracustr (custname, Sccustorders, Sccustsales) ; printf ( "Jackson %d $%d\n" , custorders, custsales) ; strcpy ( (char ) custname, "Jones") ; oracustr (custname, Sccustorders, Sccustsales) ; printf ( "Jones %d $%d\n" , custorders, custsales) ; strcpy ((char ♦) custname, "Johnson" ) ,- oracustr (custname, Sccustorders , Sccustsales) ,- printf ( "Johnson %d $%d\n" , custorders , custsales) ; strcpy ( (char ♦) custname, "Jaffe") ; oracustr (custname, Sccustorders, Sccustsales) ; printf ( "Jaffe %d $%d\n" , custorders , custsales) ,- strcpy ( (char ♦) custname, "James" ) ; oracustr (custname, Sccustorders, Sccustsales) ,- printf ( "James %d $%d\n" , custorders , custsales) ;
} close the cursors and log off from ORACLE
printf ( "\nDisconnecting from Oracle . \n" ) ; oradisc 0 ; printf ("\nEnd of OpenMQ/Pro^C example .\n" ) ; return;
}
/*
COUNT askn (text, variable) print the ' text ' on STDOUT and read an integer variable from SDTIN. text points to the null terminated string to be printed variable points to an integer variable askn returns a 1 if the variable was read successfully or a -1 if -eof- was encountered
int askn (tex , variable) char text [j ,- int *variable,-
{ char s [20] ,- printf (text) ,- f f lush (stdout) ; if ( gets (s) == (char *) 0 ) return (EOF) ;
♦variable = atoi (s) ;
return (1) ; }
/*
COUNT asks (text, variable) print the 'text' on STDOUT and read up to 'len' characters into the buffer pointed to by variable from STDIN. text points to the null terminated string to be printed variable points to a buffer of at least 'len'+l characters asks returns the number of character read into the string, or a -1 if -eof- was encountered
*/ int asks (text , variable) char text [] , variable [] ;
{ printf (text) ; fflush(stdout) ,- return( gets (variable) == (char JO ? EOF : strlen (variable) ) ;
/* **
** Copyright (C) 1996 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
** OR DISCLOSURE.
**
** THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
** TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
** OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
** OpenMQ Demo
** Module: oratest.pc
** Author: Frederick J. Igo, Jr. 1/15/96
**
*/ ttinclude <stdlib.h> ttinclude <stdio.h> ttinclude <ctype.h> ttinclude <string.h>
# include "sqlproto.h" ϋ include "ociproto.h"
# define ORACLE tt include "oraomq. h"
/* NAME openmq FUNCTION
Simple openmq Pro^C sample program NOTES openmq is a simple example program which decrements the stock for ordered items. Checking is done for sufficient stock.
The program queries the user for data as follows:
Enter customer name: Enter item name: Enter quantity ordered:
The program terminates if null string (<return> key) is entered when the customer name is requested.
If the item qty is updated, the following is printed:
"Order for QTY ITEM at PRICE has been placed"
C: \ORANT\PR016\C> nmake -f openmq.mak
OWNER Igo DATE
01/11/96 MODIFIED igo 01/11/96 - create from sample32.pc */
void mainO
( char itemname [10] ; /* item name / int itemprice; /* item price / int itemqty; /* item quantity ♦/ char custname [10] ; /* cust name / int custorders; /* cust ttorders ♦/ int custsales; /* cust $sales / char orastring [80] ,- /* Oracle ID / char orastrinp [80] ; /* Oracle ID ♦/
logon to ORACLE, and open the cursors. The program exits if any errors occur.
strcpy ( (char ♦) orastring, "SCOTT/TIGER@T :GRAMPA: ORCL" ) ,- if (asks ("\nAlter connect string? (null keeps SCOTT/TIGEROT : ORACLE : ORCL) (char ♦) orastrinp) > 0 ) ( strcpy((char *) orastring, (char ) orastrinp) ; } printf ( "\nConnecting to Oracle using string %s . .. " , orastring) ,- if (oraconn (orastring) == 1) ( oraerrrpt ( ) ; printf ("SQL Error on CONNECT, Bye-bye."); return;
} printf ( "connected. \n" ) ;
/ Create/Fill DB / if ( asks ( "\nShall we create/clear the DB (non-null to create)?", (char ♦) custname) > 0 ) ( printf ( "Creating omq_stock and omq_cust tables in Oracle ... \n" ) if (oracreate 0 == 1) { oraerrrpt ( ) ; printf ("SQL Error on CREATE, Bye-bye."); return;
Read the user's input from STDIN. If the item name is not entered, exit. Verify that the entered quantity is lessthan that item's stock.
for( ; ,- )
{ int 1, tot, qtyo ,-
/ Get customer name / 1 = asks ("\nEnter customer name (null to quit): ", (char ♦)custname); if ( 1 <= 0 ) break; printf (" Checking Customer %s in DB ... ", custname) ; switch (oracustr (custname, Sccustorders, Sccustsales) ) { case 1 : { oraerrrpt ( ) ; printf ("SQL Error on Customer DB Read, try again. \n"); continue;
} case 2 : ( printf ("No such customer, try again. \n"),- continue ,-
/♦ Get item name to be ordered ♦/ asks ( "\nEnter item name : ", (char *) itemname);
/* Read DB with given item name to get qty and price ♦/ printf (" Checking item in DB ... " ) ; switch (oraread (itemname, Seitemprice, Scitemqty) ) ( case 1 : ( oraerrrpt ( ) ; printf ("SQL Error on Customer DB Read, try again. \n") ; continue; case 2 : { printf ("No such item, try again. \n"); continue ;
askn ( "\nEnter quantity ordered: " , Scqtyo) ,- printf (" Checking stock for %d %s... ", qtyo, itemname) ; if (qtyo > itemqty) printf ( "Insufficient stock: %d. \n" , itemqty) ,- continue; }
/ Here if item was found in dbs and quantity suffucient. ♦/ itemqty -= qtyo; tot = qtyo ♦ itemprice;
/ Update DB for given item name ♦/ printf ("Updating %s QTY in Stock DB. \n" , itemname) ,- switch (orawrite (itemname, itemqty) ) ( case 0 : ( printf ("\nOrder for %d %s at $%d each placed, ", qtyo, itemname, itemprice) ; printf ("Sale is $%d, %d %s remain. \n", tot, itemqty, itemname) ; break ,- case 1 : ( oraerrrpt ( ) ;
printf ( "SQL Error during DB update , order not placed . \n" ) ,- break ;
} case 2 : {
/ Shouldn't get this case, since read found item ♦/ printf ("No such item on write, please start over ... \n" ) ; break;
/ Update Cust DB / custorders += 1; custsales += tot; switch (oracustw (custname, custorders, custsales) ) { case 0 : { printf ("%s has placed %d orders for $%d.\n", custname , custorders , custsales) ; break;
} case 1 : { oraerrrpt ( ) ; printf ("SQL Error during cust DB update . \n" ) ; break; case 2 : (
/ Shouldn't get this case, since read found item ♦/ printf ("No such customer on write, please start over\n"); break ,-
printf ("ITEM PRICE QTY\n"); strcpy ( (char ♦) itemname, "Bolts") ; oraread (itemname, Seitemprice, Scitemqty) ; printf ("Bolts $%d %d\n" , itemprice, itemqty) ; strcpy ( (char *) itemname, "Buckets") ,- oraread (itemname , Seitemprice , Scitemqty) ; printf ("Buckets $%d %d\n" , itemprice, itemqty) ,- strcpy ( (char *) itemname, "Buttons") ,- oraread (itemname, Seitemprice, Scitemqty) ,- printf ( "Buttons $%d %d\n" , itemprice, itemqty) ; strcpy((char ♦) itemname, "Belts" ) ,- oraread ( itemname , Seitemprice , Scitemqty) ; printf ("Belts $%d %d\n" , itemprice, itemqty) ,- strcpy ( (char *) itemname, "Bobbins") ,- oraread (itemname , Seitemprice , Scitemqty) ; printf ( "Bobbins $%d %d\n" , itemprice, itemqty) ; strcpy ( (char ♦) itemname, "Boats") ; oraread ( itemname , Seitemprice , Scitemqty)
printf ( " Boats $%d %d\n" , itemprice , itemqty) ;
printf ("=============================\n") ,- printf ("CUSTOMER ORDERS SALES\n"); strcpy ( (char ) custname, "Jacobs") ,- oracustr (custname, Sccustorders, Sccustsales) ,- printf ( "Jacobs %d $%d\n" , custorders, custsales) ; strcpy( (char )custname, "Jackson") ; oracustr (custname, Sccustorders , Sccustsales) ; printf ("Jackson %d $%d\n" , custorders , custsales) ; strcpy ( (char ) custname, "Jones") ; oracustr (custname, kcustorders, Sccustsales) ; printf ("Jones %d $%d\n" , custorders, custsales) ,- strcpydchar ♦) custname, "Johnson" ) ; oracustr (custname, Sccustorders, Sccustsales) ; printf ("Johnson %d $%d\n" , custorders, custsales) ; strcpy ( (char *) custname, "Jaffe" ) ,- oracustr (custname, Sccustorders, Sccustsales) ,- printf ( "Jaffe %d $%d\n" , custorders, custsales) ,• strcpy ((char *) custname , "James" ) ; oracustr (custname, Sccustorders, Sccustsales) ; printf ( "James %d $%d\n" , custorders, custsales) ,-
close the cursors and log off from ORACLE
printf ("\nDisconnecting from Oracle. \n"); oradisc () ; printf ( "\nEnd of OpenMQ/Pro+C example . \n" ) ,- return ;
/*
COUNT askn (text, variable) print the ' text ' on STDOUT and read an integer variable from
SDTIN. text points to the null terminated string to be printed variable points to an integer variable askn returns a 1 if the variable was read successfully or a -1 if -eof- was encountered
int askn (text ,variable) char text [j ; int variable;
char s [20] ; printf (text) ; fflush (stdout) ,- if ( gets(s) == (char * ) 0 ) return (EOF) ;
♦variable = atoi(s); return (1) ;
}
/*
COUNT asks (text, variable) print the 'text' on STDOUT and read up to 'len' characters into the buffer pointed to by variable from STDIN. text points to the null terminated string to be printed variable points to a buffer of at least 'len'+l characters asks returns the number of character read into the string, or a -1 if -eof- was encountered
int asks (text , ariable) char text [j , variable [] ,-
{ printf (text) ,- fflusht stdout) ; return ( gets (variable) == (char * ) 0 ? EOF : strlen (variable) )
}
User: root Host: bunny Class : bunny Job: stdin
00037
SETUP :
Install SQL^Net TCP\IP Client 1.1.6.8 on client.
Install Pro^C 1.6.4.0.1.
For execution you only need C:\ORANT\PR016\LIB\SQLNT16.DLL. I've saved a copy here for execution of oratest, if Pro^C is not installed.
For building a .pc file, you need Pro^C installed.
Add "C:\ORANT\BIN" to system Path variable to pickup Oracle DLLs.
(A copy of MSVCR40.DLL is saved here for execution of oratest.exe, if MSVC 4.0 is not installed.)
NOTES :
ORATES'T currently uses oracleid SCOTT/TIGEROT : GRAMPA:ORCL, but this can be altered when prompted for a connect string.
ORATEST can be used to verify the install on SQL+NET.
ORATEST can create the omq_stock and omq_cust tables in Oracle.
ORATEST can be used to view the omq_stock and omq_cust tables .
/* **
♦♦ Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
♦♦ UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
♦* LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
♦♦ IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
♦♦ OR DISCLOSURE.
**
♦* THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
** TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
♦♦ OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
♦♦ EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
♦♦ OpenMQ
♦♦ Module: putu.cpp
♦♦ Author: Derek Schwenke 9/8/95
*/
// putu.cpp : Defines the class behaviors for the application.
// ttinclude "stdafx.h" ttinclude "putu.h" ttinclude "putudlg.h" ttifdef JDEBUG ttundef THISJFILE static char BASED_CODE THIS_FILE [ ] = FILE ; ttendif
///////////////////////////////////////////////////////////////////////////// // CPutuApp
BEGIN_MESSAGE_MAP (CPutuApp, CWinApp) // { {AFXJMSGJMAP (CPutuApp)
// NOTE - the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see in these blocks of generated code //}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp : :OnHelp) END_MESSAGE_MAP ( )
///////////////////////////////////////////////////////////////////////////// // CPutuApp construction
CPutuApp : : CPutuApp ( )
// TODO: add construction code here,
// Place all significant initialization in Initlnstance
}
///////////////////////////////////////////////////////////////////////////// // The one and only CPutuApp object
CPutuApp theApp;
///////////////////////////////////////////////////////////////////////////// // CPutuApp initialization
BOOL CPutuApp: : Initlnstance 0
(
// Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need.
Enable3dControls () ;
LoadStdProfileSettings () ,- // Load standard INI file options (including
CPutuDlg dig; m_pMainWnd = Sedlg,- int nResponse = dig . DoModal 0 ; if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is // dismissed with OK
} else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel }
// Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump, return FALSE;
// putu.h . mam header file for the PUTU application // ttifndef AFXWIN_H tterror include 'stdafx.h' before including this file for PCH ttendif ttinclude "resource. h" // mam symbols
/////////////////////////////////////////////////////////////////////////////
// CPutuApp.
// See putu.cpp for the implementation of this class
// class CPutuApp public CWinApp
{ public
CPutuApp ( ) ,
// Overrides
// ClassWizard generated virtual function overrides // { {AFXJVIRTUAL (CPutuApp) public • virtual BOOL Initlnstance 0 ; //} }AFXJVIRTUAL //virtual void printer ( char *mess ),
// Implementation
// { {AFXJMSG (CPutuApp)
// NOTE - the ClassWizard will add and remove member function II DO NOT EDIT what you see in these blocks of generated code
//} }AFXJMSG
DECLARE MESSAGE MAP 0
}; "
/////////////////////////////////////////////////////////////////////////////
// putudlg.cpp : implementation file // ttinclude "stdafx.h" ttinclude "putu.h" ttinclude "putudlg.h" ttinclude "putuqopt.h" ttinclude "putumopt.h" ttinclude "qlib.h"
//ttinclude <windowsx.h> // ListBox_AddString
//extern IpRT RTroot;
//////////////////////////////////////// lpQHANDLE Q ; extern IpSMBUFH sm base;
//////////////////////////////////////// ttifdef JDEBUG ttundef THIS_FILE stat ic char BASEDJDODE THIS_FILE [ ] = FILE ; ttendif I lllll III III I II I
II CAboutDlg dialog used for App About class CAboutDlg : public CDialog
{ public :
CAboutDlg ( ) ;
// Dialog Data
//{ {AFXJDATA (CAboutDlg) enum { IDD = IDD_ABOUTBOX } ; //} }AFXJDATA
// Implementation protected: virtual void DoDataExchange (CDataExchange^ pDX) ; // DDX/DDV suppo
//{ (AFX_MSG (CAboutDlg) virtual BOOL OnlnitDialog 0 ;
//}}AFX_MSG
DECLARE_MESSAGE_MAP ( )
CAboutDlg :: CAboutDlg 0 : CDialog (CAboutDlg :: IDD)
// { (AFXJDATAJINIT (CAboutDlg) //}}AFX DATA INIT
void CAboutDlg: : DoDataExchange (CDataExchange^ pDX)
CDialog: -.DoDataExchange (pDX) ; // { (AFX DATAJMAP (CAboutDlg) //}}AFX DATA MAP
BEGIN_MESSAGE_MAP (CAboutDlg, CDialog) //{ AFX MSG MAP (CAboutDlg)
~ " 000378 // No message handlers //} }AFXJMSGJMAP ENDJMESSAGEJMAP ( )
///////////////////////////////////////////////////////////////////////////// // CAboutDlg message handlers
BOOL CAboutDlg: :OnInitDialog()
{
CDialog: :OnInitDialog ( ) ;
CenterWindow ( ) ;
// TODO: Add extra about dig initialization here return TRUE; // return TRUE unless you set the focus to a control }
///////////////////////////////////////////////////////////////////////////// // CPutuDlg dialog
CPutuDlg: : CPutuDlg (CWnd pParent /♦=NULL^/) : CDialog (CPutuDlg :: IDD, pParent)
{
//{ (AFXJDATA_INIT (CPutuDlg) m_qnames = _T ( " " ) ,- m_message = _T("") m_qstatus = _T ( " " ) m_mstatus = _T ( " " ) // } }AFXJDATA_INIT
// Note that Loadlcon does not require a subsequent Destroylcon in Wiγ-",°. m hlcon = AfxGetApp () - >LoadIcon (IDR MAINFRAME);
} void CPutuDlg: : DoDataExchange (CDataExchange^ pDX)
CDialog: : DoDataExchange (pDX) ; // { (AFX_DATA_MAP (CPutuDlg) DDX_CBString(pDX, IDCJQNAMES, m_qnames) ; DDXJText (pDX, IDC_MESS, m_message) ,- DDXJText (pDX, IDCJ2STATUS, m_qstatus) ; DDX Text(pDX, IDC_MSTATUS, m_mstatus) ; // }TAFXJDATAJMAP
)
Figure imgf000381_0001
///////////////////////////////////////////////////////////////////////////// // CPutuDlg message handlers
BOOL CPutuDlg : : OnInitDialog ( )
{
CDialog: :OnInitDialog () ; CenterWindowO ,-
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range. ASSERT ( (IDM_ABOUTBOX & OxFFFO) == IDM_ABOUTBOX) ; ASSERT (IDM_ABOUTBOX < OxFOOO);
CMenu* pSysMenu = GetSystemMenu (FALSE) ; CString strAboutMenu; strAboutMenu . LoadString ( IDS_ABOUTBOX) ; if (! strAboutMenu. IsEmpty () )
{ pSysMenu->AppendMenu (MF_SEPARATOR) ; pSysMenu->AppendMenu(MF_STRING, IDMJABOUTBOX, strAboutMenu);
// Set printing window for "C" code CWnd^ pLogWin = this->GetDlgIte ( IDC_PRINTER) ; SetWinPtr (pLogWin->m_hWnd) ;
/////////////////////////////////////////////// minium ii QUE PULL DOWN III mmnii/i III mmmimimmmimmmmmmi/m
CComboBox * QR = (CComboBox ) this- >GetDlgItem ( IDCjQNAMES) ; //CB->AddString("INITALl") ,- IpRT rtp = GetRTroot (); while (rtp) { char ♦e^s = rtp->apps; // Starts after the first letter while (e = strchr (s, ',') ) { // Ends at next "," e = 0; if ( !strchr(s, ' [' ) ) CB->AddString(s) ;
S = e + 1 ;
} rtp = rtp->next;
return TRUE; // return TRUE unless you set the focus to a control } void CPutuDlg: : OnSysCommand (UINT nlD, LPARAM IParam) if ( (nlD Sc OxFFFO) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout; dlgAbout . DoModal ( ) ;
} else
CDialog: :OnSysCommand (nlD, IParam) ; } }
// If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework.
void CPutuDlg: :OnPaint ()
{ if (Islconic ( ) )
(
CPaintDC dc(this); // device context for painting
SendMessage (WM_ICONERASEBKGND, (WPARAM) dc .GetSafe«dc 0 , 0);
// Center icon in client rectangle u int cxlcon = GetSystemMetrics (SMJDXICON) ; int cylcon = GetSystemMetrics (SM_CYICON) ,-
CRect rect ;
GetClientRect (Srect) ; int x = (rect. Width () - cxlcon + 1) / 2 ,- mt y = (rect .Height () - cylcon + 1) / 2;
// Draw the icon dc.DrawIcon (x, y, mjnlcon) ,- else
CDialog : : OnPaint ( ) ;
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CPutuDlg: :OnQueryDragIcon 0 return (HCURSOR) hlcon; } void CPutuDlg: :OnButQOpen()
{ int status; char qname [100] , line [100] ,-
SetDlgltemText ( IDCJQSTATUS , "Opening... ") ;
GetDlgltemText ( IDC_QNAMES , qname , 100) ;
ReadParms ( ) ,- if ( ! (Q = Qopen(qname, PUTTING, 0, 0, 0, 0, 0) ) ) sprintf (line, "FAILED to open %s", qname); else sprintf (line, "OPENED %s", qname) ;
SetDlgltemText (IDC QSTATUS, line) ; } void CPutuDlg: :OnButQclose () {
SetDlgltemText (IDC QSTATUS , "CLOSED") ; } void CPutuDlg: :OnButSend() char got [100], line [100] ;
GetDlgltemText ( IDCJMESS, got , 90) ; sprintf (line, "Sending: %s" , got) ,- // C++ does this better?
SetDlgltemText ( IDCJMSTATUS , line) ;
SetDlgltemText (IDC_MESS, "") ,- // Blank out the message
// How do I force these to print out here? // PeekMessage // AddltemO ,-
if (QSUCCESS != Qput (Q, 0,0, 0 , sizeof (got ), got ) ) sprintf (line, "FAILED to send : %s ", got ) ,- else sprintf (line, "Sent :%s" ,got) ; SetDlgltemText ( IDC_MSTATUS , line) ;
}
/* void CPutuDlg : sprinter (char ♦mess) {
// CEdit : :SetWindowText CEdit ♦ CE = (CEdit ♦) this->GetDlgItem (IDCJPRINTER) ;
//CEdit ♦ CE = (CEdit ♦) GetDlgltem (IDC_PRINTER) ;
//CE->GetWindowText (" ") ; CE->SetWindowText ("NEW TEXT 1 \n SECOND LINE \n"); } void printer (char mess) {
SetDlgltemText (IDCJMESS, mess) ;
*/ void CPutuDlg: :OnButQopts 0
CPutuQOpts qopt;
TRACE ("AT QOPTS BUTTON"); int nResponse = qopt .DoModal 0 ,- if (nResponse == IDOK)
// TODO: Place code here to handle when the dialog is // dismissed with OK
} else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is // dismissed with Cancel
} void CPutuDlg : : OnButMopts ( )
{
// TODO: Add your control notification handler code here
TRACE ("AT MOPTS BUTTON");
CPutuMOpts mopt; int nResponse = mopt .DoModal () ,- if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is // dismissed with OK
} else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
00038 // putudlg . h : header file // ii/ii/ii ii i
II CPutuDlg dialog class CPutuDlg : public CDialog
{
// Construction public :
CPutuDlg (CWnd pParent = NULL); // standard constructor
// Dialog Data
//{ {AFXJDATA (CPutuDlg) enum { IDD = IDD_PUTUJDIALOG } ;
CString m_qnames;
CString m_message;
CString m_qstatus;
CString m_mstatus;
//} }AFXJDATA
// ClassWizard generated virtual function overrides // { {AFX_VIRTUAL (CPutuDlg) protected: virtual void DoDataExchange (CDataExchange^ pDX) ; // DDX/DDV suppo //}}AFXJVIRTUAL // void printer ( char mess ) ; // This worked
// Implementation protected:
HICON mjhlcon;
// Generated message map functions
LPARAM IParam);
Figure imgf000386_0001
/ **
** Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
*♦ IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
♦♦ OR DISCLOSURE.
**
♦♦ THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
♦♦ TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
♦♦ OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
**
** OpenMQ
♦♦ Module: putumopt . c
♦♦ Author: Derek Schwenke 9/8/95
*/
// putumopt . cpp : implementation f ile // ttinclude " stdafx . h" ttinclude "putu . h " ttinclude "putumopt . h" ttifdef JDEBUG ttundef THIS_FILE static char BASED_CODE THIS_FILE [ ] = , FILE ,- ttendif
///////////////////////////////////////////////////////////////////////////// // CPutuMOpts dialog
CPutuMOpts: :CPutuMOpts (CWnd* pParent /*=NULL*/) : CDialog (CPutuMOpts :: IDD, pParent)
// { {AFX_DATA_INIT (CPutuMOpts)
// NOTE: the ClassWizard will add member initialization here // } }AFX_DATA_INIT
void CPutuMOpts :: DoDataExchange (CDataExchange* pDX)
{
CDialog: : DoDataExchange (pDX) ,- // { {AFXJDATAJMAP (CPutuMOpts)
// NOTE: the ClassWizard will add DDX and DDV calls here //} }AFX DATA MAP
BEGIN_MESSAGE_MAP (CPutuMOpts, CDialog)
//{ {AFX_MSG_MAP (CPutuMOpts)
// NOTE: the ClassWizard will add message map macros here
//} }AFX_MSG_MAP END_MESSAGE_MAP ( )
///////////////////////////////////////////////////////////////////////////// // CPutuMOpts message handlers
// putumopt. h : header file //
///////////////////////////////////////////////////////////////////////////// // CPutuMOpts dialog class CPutuMOpts : public CDialog
{
// Construction public :
CPutuMOpts (CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{ {AFXJDATA (CPutuMOpts) enum { IDD = IDDJMESSJDPTS } ;
// NOTE: the ClassWizard will add data members here //} }AFXJDATA
// Overrides
// ClassWizard generated virtual function overrides
//{ {AFXJVIRTUAL (CPutuMOpts) protected : virtual void DoDataExchange (CDataExchange* pDX) ,- // DDX/DDV support
//} }AFXJVIRTUAL
// Implementation protected:
// Generated message map functions //{ {AFX_MSG (CPutuMOpts)
// NOTE: the ClassWizard will add member functions here //} }AFXJMSG DECLARE MESSAGEJMAP ( )
/* **
♦♦ Copyright (C) 1995 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED.
♦♦ UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
♦♦ LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE
♦♦ IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
♦♦ OR DISCLOSURE.
**
♦♦ THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
♦♦ TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE,
♦♦ OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
** EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA. **
** OpenMQ ♦♦ Module: putuqopt.c ♦♦ Author: Derek Schwenke 9/8/95
*/
// putuqopt . cpp : implementation file
// ttinclude " stdafx . h" ttinclude "putu . h " ttinclude "putuqopt . h" ttifdef JDEBUG ttundef THISJFILE static char BASEDJDODE THIS_FILE [] = FILE ; ttendif i ImI CiPumtuQiOipmtsidimialomg miiimiii mmmiim/im/mmmm/miimm
CPutuQOpts: :CPutuQOpts(CWnd* pParent /*=NULL*/) : CDialog (CPutuQOpts: : IDD, pParent)
//{ {AFX_DATA_INIT (CPutuQOpts) m_log_sw = FALSE; m_trace_sw = FALSE; m_tran_sw = FALSE; //} }AFX_DATA_INIT
void CPutuQOpts :: DoDataExchange (CDataExchange4 pDX)
;
Figure imgf000390_0001
BEGIN_MESSAGE_MAP (CPutuQOpts , CDialog)
// { {AFX_MSG_MAP (CPutuQOpts)
// NOTE: the ClassWizard will add message map macros here
//}}AFX_MSG_MAP END MESSAGE MAP 0
///////////////////////////////////////////////////////////////////////////// // CPutuQOpts message handlers
// putuqopt. h : header file // I
II CPutuQOpts dialog class CPutuQOpts : public CDialog
{
// Construction public :
CPutuQOpts (CWnd pParent = NULL); // standard constructor
// Dialog Data
//{ {AFXJDATA (CPutuQOpts) enum { IDD = IDDJDPENJOPTS } ; BOOL m_log_sw; BOOL m_trace_sw; BOOL m_tran_sw; //} }AFXJDATA
// Overrides
// ClassWizard generated virtual function overrides
//{ {AFXJVIRTUAL (CPutuQOpts) protected: virtual void DoDataExchange (CDataExchange* pDX) ; // DDX/DDV support
//} }AFXJVIRTUAL
// Implementation protected:
// Generated message map functions //{ {AFX_MSG (CPutuQOpts)
// NOTE: the ClassWizard will add member functions here //} }AFX_MSG DECLARE MESSAGE MAP ( )
}; "
//{ {NOJDEPENDENCIES} }
// Microsoft Visual C++ generated include file. // Used by putu.rc // ttdefine IDM_ABOUTBOX 0x0010 ttdefine IDD_ABOUTBOX 100 ttdefine IDS_ABOUTBOX 101 ttdefine IDDJPUTUJDIALOG 102 ttdefine IDC_PRINTER 104 ttdefine IDRJMAINFRAME 128 ttdefine IDDJDPENJDPTS 130 ttdefine IDDJMESSJDPTS 131 ttdefine IDC_QNAMES 1000 ttdefine IDCJMESS 1004 ttdefine IDC_BUT_Q_OPEN 1005 ttdefine IDC_BUT_SEND 1006 ttdefine IDC_BUT_QCLOSE 1007 ttdefme IDC_QSTATUS 1008 ttdefine IDCJMSTATUS 1009 ttdefine IDC_BUT_QOPTS 1010 ttdefine IDCJBUTJMOPTS 1011 ttdefine IDC_LOG_SW 1018 ttdefine IDC_TRACE_SW 1019 ttdefine IDC_TRAN_SW 1020 ttdefine IDC_TRAN_SW2 1021 ttdefine IDC TRAN SW3 1022
// Next default values for new objects
// ttifdef APSTUDIOJINVOKED ttifndef APSTUDIOJREADONLY_SYMBOLS ttdefine JAPSJSTEXTJRESOURCEJVALUE 132 ttdefine _APS_NEXT_COMMAND_VALUE 32771 ttdefine _APSJNEXT_CONTROL_VALUE 1019 ttdefine _APSJNEXT_SYMED_VALUE 101 ttendif ttendif
/*
* *
** Copyright (C) 1996 MITSUBISHI ELECTRIC ITA. ALL RIGHTS RESERVED. ** UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT ** LAWS OF THE UNITED STATES. USE OF A COPYRIGHT NOTICE ** IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION ** OR DISCLOSURE. ** + * THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE SECRETS OF MITSUBISHI ELECTRIC ITA. USE, DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
* * EXPRESS WRITTEN PERMISSION OF MITSUBISHI ELECTRIC ITA.
* * OpenMQ Demo ** Module : oraomq . h ** Author : Derek Schwenke 1/ 11/96 **
*/
ttifdef CPP extern " C"
{ ttendif
ttifdef ORACLE int orawrite ( char itemname [10] , int itemqty) ; int oraread ( char itemname [10] , int itemprice, int itemqty); int oracustw ( char custname [10] , int custorders, int custsales); int oracustr ( char custname [10] , int custorders, int ♦custsales) int oradisc ( ) ,- int oraconn ( char orastring [80] ) ; int oracreate () ; int oraerrrpt () ; ttelse int orawrite ( char itemname [10] , int itemqty) int oraread ( char itemname [10] , int itemprice, int itemqty) int oracustw ( char custname [10] , int custorders, int custsales) int oracustr ( char custname [10] , int custorders, int ♦custsales) int oradisc () int oraconn ( char orastring [80] ) int oracreate ( ) int oraerrrpt ( ) ttendif
ttifdef CPP
} ttendif
// Demo app ' s order form typedef struct oform { // Thread parameters char cust [10] ; char item [10] ; int qty; int color; int reply to;
OFORM, *pOFORM, *lpOFORM;
// dbdlg.cpp : implementation file // ttinclude "stdafx.h11
//ttinclude "oentrvw. h"
ttinclude " oentry. h" ttinclude "dbdlg.h" ttinclude "Odlg.h"
// ttdefine ORACLE causes oraread 0 orawrite () to be exteraly defined ttifndef ORACLE ttdefine ORACLE ttendif ttinclude "oraomq. h"
ttifdef JDEBUG ttundef THIS_FILE static char BASEDJDODE THIS_FILE[] = FILE ; ttendif ttdefine DBJTIMER 200 ttdefine INIT_TIMER 10 ttdefine RESTOCK_QTY 10000 int g_orders_mode = 0; // Display orders or items extern CString g_item[] ,- extern CString g_cust [] ; extern int g_price[6],- extern int g_qty[6] ; int g_qty_old [6] ; extern int g_purchases [6] ,- int g_purchases_old [6] ; extern int g_num_purchases [6] ; int g_num_purchases_old [6] ; extern int g_total_sales; int g_total_sales_old; extern int g_db_run; extern int g_ora_state,- int g_ora_state_old = -1; extern CFont g_title_font ; extern CFont g__text_font ; enum dblDC {qtyJIDC,price_IDC, item_IDC} ; int ALL TEXT DB[] { IDCJDRDERS_ITEMS , IDC_DB_REFILL, IDC_DBJBOX, IDOK,
IDC_DB_SALEST, IDC_DB_SALES ,
IDC_T11 , IDCJT12 , IDC_T13 ,
IDCJT21, IDC_T22,IDC_T23,
IDCJDB JQ0 , IDC_DB_Q1 , IDCJDBJQ2 , IDCJDBJQ3 , IDC DBJQ4 , IDCJDB_Q5
IDC_DB_P0 , IDC_DB_P1 , IDC_DB_P2 , IDC_DB_P3 , IDC_DB_P4 , IDC_DB \
IDC DB_I0,IDC_DB I1,IDC_DB I2,IDC_DB 13, IDC DB 14 , IDC DB -...J int g_IDCt [2] [3] ={ IDC_T11 , IDCJT12 , IDC_T13 IDC T21,IDC T22,IDC T23 }; int g IDCs[3] [6] = { IDC_DB_Q0 , IDC_DB_Q1 , IDC_DB_Q2 , IDC_DB_Q3 , IDCJDB_Q4 , IDC_DB_Q
( IDC_DB JPO , IDC_DB_P1 , IDC_DB_P2 , IDC JDB_P3 , IDCJDB_P4 , IDC_DB_P5 IDC_DB_I0, IDC_DB_I1, IDC_DB 12 , IDC_DB_I3 , IDC_DB_I4 , IDC_DB_I5 CString g_item_tites [] = { "Qty" , "Price" , "Item"T; CString g_order_titles [] = {"#", "Amt ", "Customer" } ;
III I lllll II II llll Ill/Ill II lllll II CDbDlg dialog
CDbDlg: :CDbDlg(CWnd* pParent /*=NULL*/) : CDialog (CDbDlg :: IDD, pParent)
//{{AFX_DATA_INIT (CDbDlg)
// NOTE: the ClassWizard will add member initialization here //} }AFX_DATA_INIT
void CDbDlg: : DoDataExchange (CDataExchange♦ pDX)
{
CDialog: : DoDataExchange (pDX) ; // { {AFXJDATAJMAP (CDbDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here // } }AFX_DATA_MAP
Figure imgf000397_0001
///////////////////////////////////////////////////////////////////////////// // CDbDlg message handlers void CDbDlg: : OnOrdersItems ()
{ int i , j ; CString s; if (g_orders_mode) { // Go into Items mode g_orders_mode = 0 ; SetDlgltemText (IDCJDBJREFILL, "Refill") ;
// Set DB titles
SetDlgltemText (IDCJDBJBOX, "Database Items" ) ;
SetDlgltemText (IDC_ORDERS_ITEMS, "Orders") ; for (i=0;i<2;i++) for (j=0; j<3 ; j++)
SetDlgltemText (g_IDCt [i] [j] , g_item_tites [j] ) ; // Set DB values for (i = 0; i<6 ,-i++){ // For each item
SetDlgltemlnt (g_IDCs [qty_IDC] [i] ,g_qty[i]),- s. Format ("$%d.00" ,g_price [i] ) ;
SetDlgltemText (g_IDCs [priceJIDC] [i] ,s) ,-
SetDlgltemText (g_IDCs [item_IDC] [i] ,g item[i] ) ;
}
} else { // Go into Orders mode g_orders_mode = 1 ; SetDlgltemText (IDCJDBJREFILL, "Clear") ,-
// Set DB titles
SetDlgltemText (IDCJDBJBOX, "Database Orders") ; SetDlgltemText (IDC_ORDERS_ITEMS, "Items") ; for (i = 0 ; i<2,-i + + ) for ( j=0; j<3; j++)
SetDlgltemText (g_IDCt [i] [j] , g_order_titles [j] // Set DB values for (ι=0; i<6 ;i++){ // For each item
SetDlgltemlnt (g_IDCs [qtyJIDC] [i] , g_num_purchases [i] SetDlgltemlnt (g_IDCs [price_IDC] [i] , g_purchases [i] ) ; SetDlgltemText (g_IDCs [item_IDC] [i] ,g_cust[i] ) ;
} for (i=0; i<6 ;i++){ // Invalidate any histoy g_num_purchases_old [i] = g_purchases_old [i] = g qty old[i] = -1;
} " ~
} void CDbDlg: :OnTimer (UINT nIDEvent)
{ int i, re, price, stock, cust_orders , cust_sales,-
CString s,- if (nIDEvent == DB_TIMER) { if (g_db_run < 20) { if (g_db_run == 0) this->DestroyWindow ( ) ,- if (g_db_run == 1) {g_orders_mode = 1; OnOrdersItems 0 ,- g_db_run = 20,-} if (g_ora_state) { // oracle db if (g_orders_mode) { for (i = 0; i<6 ,-i++){ // For each item if ( (re = oracustr (g_cust [i] .GetBuf fer (0) , &cust_orders, Secust_ s. Format ( "OraCustRead ErroR %d",rc) ; GetParentFrame 0 ->SetMessageText (s) ,- if (g_num_purchases_old[i] != cust_orders)
SetDlgltemlnt (g_IDCs [qtyJIDC] [i] , (g_num_purchases_old [i] = c if (g_purchases_old [i] != cust_sales)
SetDlgltemlnt (g_IDCs [price_IDC] [i] , (g_purchases_old [i] = cu
} else { for (i=0; i<6 ;i++) { // For each item
if ( (re = oraread (g_item[i] .GetBuf fer (0) , Scprice, Sestock) ) ) { s .Format ("OraRead ErroR %d",rc); GetParentFrame () ->SetMessageText (s) ;
} if (g_qty_old [i] != stock)
SetDlgltemlnt (g_IDCs [qty_IDC] [i] , (g_qty_old [i] = stock) ) ;
} else if (g_orders_mode) { // NOT ora_state, so use the local db for (i=0; i<6 ;i++) { // For each item if (g_num_purchases_old [i] != g_num_purchases [i] )
SetDlgltemlnt (gJIDCs [qty_IDC] [i] , (g_num_purchases_old [i] = g_nu if (g_purchases_old [i] != g_purchases [i] )
SetDlgltemlnt (g_IDCs [price_IDC] [i] , (g_purchases_old [i] = g_purcha
} else { // local db for (i=0; i<6 ;i++){ // For each item if (g_qty[ij != g_qty_old [i] ) SetDlgltemlnt (g_IDCs [qty_IDC] [i] , (g_qt-y_old [i] = g_qty [i] ) ) ;
if (g_total_sales_old != g_total_sales)
SetDlgltemlnt (IDC_DB_SALES, (g_total_sales_old = g_total_sales) ) ,-
if (g_ora_state_old != g_ora_state) { if (g_ora_state_old = g_ora_state)
SetDlgltemText (IDC_BIG_TITLE, "Oracle") ,- else
SetDlgltemText (IDC BIG TITLE, "Local DB");
} else if (nIDEvent == INIT_TIMER) { KillTimer (INIT TIMER);
GetDlgltem (IDC_BIG_TITLE) ->SetFont (&g_title_font) if (g_ora_state)
SetDlgltemText (IDCJBIG_TITLE, "Oracle") ; else
SetDlgltemText (IDC_BIG_TITLE, "Local DB" ) ;
} else
CDialog: :OnTimer (nIDEvent) ,-
int CDbDlg: :OnCreate (LPCREATESTRUCT IpCreateStruct)
{ if (CDialog: :OnCreate (IpCreateStruct) == -1) return -1;
SetTimer (DBJTIMER, 200, NULL) ; SetTimer ( INITJTIMER, 200 , NULL) g_db_run = 1; // Start return 0 ;
}
void CDbDlg: :OnDestroy() g_db_run = 40;
CDialog: :OnDestroy() ;
KillTimer (DB TIMER); } void CDbDlg: :OnOK()
{ g_db_run = 40; // Re enable the show db call button this->DestroyWindow() ;
// CDialog: :OnOK() ; } void CDbDlg: :OnDbRefill () int i , re ,- CString s; if (g_ora_state) { for (i=0 ,- i<6 ; i ++) { if (g_orders_mode) { if ( (re = oracustw (g_cust [i] .GetBuffer (0) , 0, 0)) ) { s. Format ("OraCustWrite ERRor %d",rc); GetParentFrame ( ) - >SetMessageText (s) ;
} else { // in items mode if (re = orawrite (g_item[i] .GetBuffer (0) , RESTOCK_QTY) ) { s .Format ("OraWrite ERRor %d",rc);
GetParentFrame ( ) - >SetMessageText ( s ) ; }
} else { for (i=0 ,- i<6; i++) { if (g_orders_mode) { g_purchases [i] = 0 ,- g_num_purchases [i] = 0; } else { // in items mode g_qty[i] = RESTOCK_QTY ;
void CDbDlg: : OnRButtonDown (UINT nFlags, CPoint point)
{
GetParentFrame ( ) - >SetMessageText ( " " ) ,- this->Invalidate () ,-
CDialog: : OnRButtonDown (nFlags, point) ,-
BOOL CDbDlg: :OnInitDialog()
CDialog: :OnInitDialog () ;
// Fonts int i = 0; while (ALLJTEXTJDB [i] )
GetDlgltem (ALLJTEXTJDB [i++] ) - >SetFont dg_text_font ) ,- return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE
// dbdlg . h : header file //
III
II C iDbDlg d iianlo ign nm IIIII i iiiiimmm in i // n iimimimimm class CDbDlg : public CDialog
{
// Construction public .-
CDbDlg (CWnd* pParent = NULL); // standard constructor
// Dialog Data
// { {AFX_DATA (CDbDlg) enum { IDD = IDDJDBDLG } ;
// NOTE: the ClassWizard will add data members here //} }AFXJDATA
// Overrides
// ClassWizard generated virtual function overrides
//{ {AFXJVIRTUAL (CDbDlg) protected : virtual void DoDataExchange (CDataExchange^ pDX) ; // DDX/DDV support
//}}AFXJIRTUAL
CFont m_title_font ; int m_was_inited;
// Implementation protected:
// Generated message map functions
// { {AFX_MSG (CDbDlg) afx_msg void OnOrdersItems 0 ; afx_msg void OnTimer(UINT nIDEvent); afx_msg int OnCreate (LPCREATESTRUCT IpCreateStruct ) ; afx_msg void OnDestroyO ; virtual void OnOK 0 ; afx_msg void OnDbRefillO; afx_msg void OnRButtonDown (UINT nFlags, CPoint point); virtual BOOL OnlnitDialog ( ) ;
//}}AFX_MSG
DECLARE MESSAGE MAP 0
NOT TO BE TAKEN INTO ACCOUNT FOR THE PURPOSE OF INTERNATIONAL PROCESSING
CMainFrame : : "CMainFrame ( )
int CMainFrame: :OnCreate (LPCREATESTRUCT IpCreateStruct)
{ if (CFrameWnd: :OnCreate (IpCreateStruct) == -1) return -1; if ( !m_wndToolBar. Create (this) ||
!m_wndToolBar . LoadBitmap ( IDRJMAINFRAME) ! m_wndToolBar . SetButtons (buttons , sizeof (buttons) /sizeof (UINT) ) )
{
TRACEO ( "Failed to create toolbar\n" ) ; return -1; // fail to create
Derek's remove tool bar / m wndToolBar. ShowWindow (SW HIDE)
if ( !m__wndStatusBar. Create (this) ||
!m_wndStatusBar . SetIndicators (indicators, sizeof (indicators) /sizeof (UINT) ) )
{
TRACEO ("Failed to create status bar\n"); return -1; // fail to create }
// TODO: Delete these three lines if you don't want the toolbar to
// be dockable m_wndToolBar .EnableDocking (CBRS_ALIGN_ANY) ;
EnableDocking(CBRS_ALIGN_ANY) ;
DockControlBar (Sem_wndToolBar) ;
// TODO: Remove this if you don't want tool tips m_wndToolBar. SetBarStyle (m_wndToolBar .GetBarStyle ( ) | CBRSJTOOL IPS | CBRSJFLYBY) ; return 0 ,- }
///////////////////////////////////////////////////////////////////////////// // CMainFrame diagnostics ttifdef JDEBUG void CMainFrame ::AssertValid () const
{
CFrameWnd: :AssertVali ( ) ;
} void CMainFrame: :Dump (CDumpContextSc dc) const
CFrameWnd: :Dump(dc) ,- } ttendif //JDEBUG
///////////////////////////////////////////////////////////////////////////// // CMainFrame message handlers
// ainfrm . h : interface of the CMainFrame class //
class CMainFrame : public CFrameWnd
{ protected: // create from serialization only
CMainFrame ( ) ;
DECLARE_DYNCREATE (CMainFrame)
// Attributes public :
// Operations public :
// Overrides
// ClassWizard generated virtual function overrides //{ {AFXJ/IRTUAL (CMainFrame) //} }AFXJVIRTUAL
// Implementation public : virtual "CMainFrame 0 ; ttifdef JDEBUG virtual void AssertValid ( ) const; virtual void Dump (CDumpContextS dc) const; ttendif protected: // control bar embedded members CStatusBar m_wndStatusBar ; CToolBar m_wndToolBar ;
// Generated message map functions protected:
// { {AFXJMSG (CMainFrame) afx_msg int OnCreate (LPCREATESTRUCT IpCreateStruct);
// NOTE - the ClassWizard will add and remove member functions h // DO NOT EDIT what you see in these blocks of generated code //}}AFX_MSG DECLARE MESSAGE MAP ( )
};
///////////////////////////////////////////////////////////////////////////// // Odlg . cpp : implementation file // ttinclude " stdafx . h " ttinclude " oentry . h" ttinclude "Odlg . h"
// ttdefine ORACLE causes oraread ( ) orawrite 0 to be exteraly def ined ttifndef ORACLE ttdefine ORACLE ttendif ttinclude " oraomq . h"
ttifdef JDEBUG ttdef ine new DEBUG_NEW ttundef THISJFILE static char THISJFILE [] = FILE ; ttendif extern int g_options_run; extern int g_fill_delay; extern int g_place_delay; extern int g_place_tpm; extern int g_poll_pps; extern int g_poll_delay; extern int g_clear_stats ,- extern int g_ora_state; extern COLORREF g_new_color; extern char g_oracle_con_str [80] ; extern CFont g_text_font; int ALLJTEXTJDΠ = { IDOK, IDCJDOLOR, IDCJLRSTATS, IDCJDRACREATE,
IDC_FILLBOX, IDCJDLYJEB, IDC DLYMAX, IDC_DLYMIN, IDC_DLY_LAB, IDC_POLL_BOX, IDC_POLL_EB, IDC_POLLMAX, IDC_POLLMIN, IDC_POLL_L IDC_AUTOBOX,IDC_AUTO_EB,IDC_AUTOMAX, IDC_AUTOMIN, IDC AUTO LA
/////////////////////////////////////////////////////////////////////////////
// COdlg dialog
COdlg: : COdlg (CWnd♦ pParent /*=NULL*/) : CDialog (COdlg :: IDD, pParent)
//{ {AFX_DATA_INIT(COdlg)
// NOTE: the ClassWizard will add member initialization here //}}AFX DATA INIT
void COdlg: : DoDataExchange (CDataExchange^ pDX)
{
CDialog: : DoDataExchange (pDX) ;
// { {AFX_DATA_MAP (COdlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX DATA_MAP
NOT TO BE TAKJEN INTO ACCOUNT FOR THE PURPOSE OF INTERNATIONAL PROCESSING
if (nSBCode == SB_ENDSCROLL) {
} else if (pScrollBar- >GetDlgCtrlID () == IDC_DLY_SLD) { if (((int)nPos != g_fill_delay) ScSc (MINJDLY <= nPos) ScSc (nPos <= R. ' SetDlgltemlnt (IDC_DLY_EB, g__fill_delay = MAX_DLY + MIN_DLY - nPos) ,- ~
} else if (pScrollBar- >GetDlgCtrlID ( ) == IDC_AUTO_SLD) { if (((int)nPos != g_place_delay) Sc& (MINJAUTO <= nPos) ScSc (nPos <= MA SetDlgltemlnt (IDC_AUTO_EB, (g_placejtpm = MAX__AUTO + MIN_AUTO - nPos) ) ; g_place_delay = 60000/g_place_tpm;
} else if (pScrollBar- >GetDlgCtrlID () == IDC_POLL_SLD) { if (((mt)nPos != g_poll_pps) ScSc (MIN_POLL <= nPos) Sc& (nPos <= MAX P SetDlgltemlnt (IDC_POLL_EB, (g_poll_pps = MAX_POLL + MINJPOLL - nPos) ) ~ g poll delay = 1000/g poll pps;
CDialog: :OnVScroll (nSBCode, nPos, pScrollBar); }
BOOL COdlg: :OnInitDialog()
{
CDialog: :OnInitDialog 0 ,-
// GetParentFrame 0 ->SetWindowText (m_inst + " Options"),- this->SetWmdowText (m__inst + " Options");
SetDlgltemlnt ( IDC_DLYMAX, MAX_DLY) ; SetDlgltemlnt (IDCJDLYMIN, MIN_DLY) ;
SetDlgltemlnt ( IDC_AUTOMAX, MAX_AUTO) ;
SetDlgltemlnt (IDC_AUTOMIN,MIN_AUTO) ;
SetDlgltemlnt (IDC_POLLMAX, MAX_POLL) ;
SetDlgltemlnt (IDC_POLLMIN,MIN_POLL) ;
SetDlgltemlnt (IDCJDLYJEB, g_fill_delay) ; SetDlgltemlnt ( IDCJPOLLJEB , g_poll_pps) ,- SetDlgltemlnt ( IDC_AUTO_EB, g_place_tpm) ;
// (CSliderCtrl ♦) xxx = GetDlgltem ( IDC_DLY_SLD) ; HWND hTrack = GetDlgltem (IDCJDLYJ3LD) ->m_hWnd; :SendMessage(hTrack,TBM_SETRANGEMIN, TRUE, MINJDLY) ;// MINDLY :SendMessage (hTrack, TBMJ3ETRANGEMAX, TRUE, MAX_DLY) ;// MAXDLY
:SendMessage (hTrack, BMJSETTICFREQ, 100, TRUE) ; // 10 ticks (MAXDLY - MINDLY : SendMessage (hTrack, TBMJ3ETP0S, RUE, MINJDLY + MAXJDLY - g_f ill_delay) ; // 1 hTrack = GetDlgltem (IDC_AUTOJSLD) ->m_hWnd; SendMessage (hTrack, TBMJ3ETRANGEMIN, TRUE, MIN_AUTO) ;// MINDLY SendMessage (hTrack, TBM_SETRANGEMAX, TRUE, MAX_AUTO) ;// MAXDLY
SendMessage (hTrack, TBM_SETTICFREQ, 500, TRUE) ; // 10 ticks (MAXDLY - MINDLY SendMessage (hTrack, TBM_SETPOS, TRUE, MAX_AUTO + MIN_AUTO - g_place_tpm) ,- // hTrack = GetDlgltem (IDCJPOLL_SLD) ->m_hWnd; SendMessage (hTrack, TBM_SETRANGEMIN, TRUE, IN_POLL) ;// MINDLY SendMessage (hTrack, TBM_SETRANGEMAX, TRUE, MAX_POLL) ;// MAXDLY SendMessage(hTrack,TBM_SETTICFREQ,10,TRUE) ; // 10 ticks (MAXDLY - MINDLY)
: : SendMessage (hTrack, TBM_SETPOS , TRUE , MAXJPOLL + MINJPOLL - g_poll_pps ) ,- // 1
// Fonts int i = 0 ,- while (ALLJTEXTJD ] )
GetDlgltem (ALLJTEXTJD [i++] ) ->SetFont Ugjtext_font) ,-
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
void COdlg: :OnUpdateAutoEb()
{ int tpm = GetDlgltemlnt (IDC_AUTOJEB, NULL, TRUE) ; if ( (g_placej_pm != tpm) ScS= (tpm >= MIN_AUTO) && (tpm <= MAXJAUTO) ) g_place_delay = 60000/tpm; g_place_tpm = tpm;
HWND hTrack = GetDlgltem ( IDC_AUTO_SLD) - >mJnWnd; : : SendMessage (hTrack, TBM_SETPOS, TRUE, MAXJAUTO + MIN_AUTO - tpm);
) ' void COdlg: :OnUpdatePollEb() int poll = GetDlgltemlnt (IDC_POLL_EB, NULL, TRUE) ; if ( (g_place_tpm != poll) &&; (poll >= MIN_AUTO) &c (poll <= MAX_AUTO) ) g_poll_delay = 1000/poll; g_poll_pps = poll;
HWND hTrack = GetDlgltem ( IDC_POLL_SLD) ->m_hWnd;
-. : SendMessage (hTrack, TBM_SETPOS, TRUE, MAXJPOLL + MIN_POLL - poll);
void COdlg: :OnUpdateDlyEb() int dly = GetDlgltemlnt (IDC_DLY_EB, NULL, TRUE) ; if ( (g_f i ll_delay ! = dly) ScSc ( dly >= MIN_DLY) ScSe (dly <= MAX_DLY) ) { g_f i ll_delay = dly ;
HWND hTrack = GetDlgltem ( IDCJDLYJ≤LD) - >m_hWnd ;
: : SendMessage ( hTrack , TBMJSETPOS , TRUE , MAXJDLY + MINJDLY - dly) ;
void COdlg: :OnColor()
{
CHOOSECOLOR cc; // common dialog box structure COLORREF acrCustClr [16] ;
// Setup the custom colors as a grey scale for (int v=0,i=0; i < 16; v=17 i++) acrCustClr [i] = RGB(v,v,v);
// Initialize the necessary members. cc.lStructSize = sizeof (CHOOSECOLOR) ; cc.hwndOwner = NULL; // = hwnd; cc.lpCustColors = (LPDWORD) acrCustClr; cc. Flags = CCJFULLOPEN; // CC_PREVENTFULLOPEN
if (ChooseColor (Sccc) ) { g_new_color = cc .rgbResult ,- // lpCustColors } else {
GetParentFrame () ->SetMessageText ( "Color was not changed")
void COdlg: :OnClrstats 0
{ g_clear_stats++ ;
void COdlg : :OnOracreate ()
(
// Create the database in oracle int org_ora_state = g_ora_state;
if (g_ora_state == 0) if (oracon (g_oracle_con_str) )
MessageBox ( "Oracle Connect Failed"); else g_ora_state = 1; if (g_ora_state) { if (oracreate 0 )
MessageBox ("Oracle oracreate Failed"),- if (org_ora_state == 0) if (oradisc ( ) )
MessageBox ("Oracle Disconnect Failed") else g_ora_state = 0 ; // Odlg.h : header file //
///////////////////////////////////////////////////////////////////////////// // COdlg dialog class COdlg : public CDialog
(
// Construction public :
COdlg (CWnd+ pParent = NULL); // standard constructor
// Dialog Data
// { {AFXJDATA (COdlg) enum { IDD = IDDJDJDLG } ;
// NOTE: the ClassWizard will add data members here //} }AFXJDATA CString m_inst ,- // COentryView^ m_parentptr;
// Overrides
// ClassWizard generated virtual function overrides
//{ {AFX_VIRTUAL (COdlg) protected: virtual void DoDataExchange (CDataExchange pDX) ; // DDX/DDV support
//} }AFX_VIRTUAL
// Implementation protected:
// Generated message map functions
//{ {AFXJMSG (COdlg) afx_msg int OnCreate (LPCREATESTRUCT IpCreateStruct); afx_msg void OnUpdateAutoEb 0 ; afx_msg void OnVScroll (UINT nSBCode, UINT nPos , CScrollBar^ pScrollBar) virtual BOOL OnlnitDialog ( ) ,- afx_msg void OnUpdatePollEb ( ) ; afx_msg void OnUpdateDlyEb () ,- afx_msg void OnColor ( ) ; virtual void OnOK 0 ; afx_msg void OnClrstats 0 ,- afx msg void OnOracreate ( ) ,-
//}ΪAFX_MSG
DECLARE MESSAGE MAP 0 // oentrdoc . cpp : implementation of the COentryDoc class // ttinclude " stdafx . h " ttinclude "oentry . h " //ttinclude "OpDlg . h" ttinclude "oentrdoc . h" tt ifdef JDEBUG ttundef THISJFILE static char BASEDJDODE THIS_FILE [] = FILE ; ttendif llll II II I II 11 III II I III III 11 II COentryDoc
IMPLEMENTJDYNCREATE (COentryDoc, CDocument)
BEGINJMESSAGEJMAP (COentryDoc, CDocument) // { {AFX_MSG_MAP (COentryDoc)
// NOTE - the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see in these blocks of generated code //} }AFXJMSGJMAP ENDJMESSAGEJMAP ( )
///////////////////////////////////////////////////////////////////////////// // COentryDoc construction/destruction
COentryDoc : : COentryDoc ( )
// TODO: add one-time construction code here
}
COentryDoc : : "COentryDoc ( )
BOOL COentryDoc : : OnNewDocument ( )
{ if ( ! CDocument : : OnNewDocument ( ) ) return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document) return TRUE; }
///////////////////////////////////////////////////////////////////////////// // COentryDoc serialization void COentryDoc: : Serialize (CArchiveSc ar)
{ if (ar . IsStoring 0 )
// TODO: add storing code here
} else
// TODO: add loading code here
II COentryDoc diagnostics ttifdef JDEBUG void COentryDoc ::AssertValid () const
CDocument: :AssertValid 0 ; } void COentryDoc :: Dump (CDumpContextSc dc) const
CDocument : : Dump (dc) ; ttendif //JDEBUG
///////////////////////////////////////////////////////////////////////////// // COentryDoc commands
// oentrdoc . h : interface of the COentryDoc class
//
///////////////////////////////////////////////////////////////////////////// class COentryDoc : public CDocument
{ protected: // create from serialization only
COentryDoc 0 ;
DECLAREJDYNCREATE (COentryDoc)
// Attributes public :
// Operations public :
// Overrides
// ClassWizard generated virtual function overrides
// { {AFX_VIRTUAL (COentryDoc) public : virtual BOOL OnNewDocument ( ) ;
//} }AFXJVIRTUAL
// Implementation public : virtual "COentryDoc 0 ; virtual void Serialize (CArchiveS ar) ; // overridden for document i/o ttifdef JDEBUG virtual void AssertValid 0 const; virtual void Dump (CDumpContextSc dc) const; ttendif protected :
// Generated message map functions protected:
//{ {AFX_MSG (COentryDoc)
// NOTE - the ClassWizard will add and remove member functions h // DO NOT EDIT what you see in these blocks of generated code //}}AFX_MSG DECLARE MESSAGE MAP ( )
}
/////////////////////////////////////////////////////////////////////////////
00041 // oentry . cpp : Defines the class behaviors for the application . // ttinclude " stdafx . h" ttinclude "oentry . h" ttinclude "mainfrm . h" ttinclude "oentrdoc . h" ttinclude "dbdlg . h" ttinclude "Odlg . h" ttinclude "oentrvw . h " ttifdef JDEBUG ttundef THIS_FILE static char BASED_CODE THISJFILE [] = FILE__; ttendif
///////////////////////////////////////////////////////////////////////////// // COentryApp
BEGIN_MESSAGEJMAP (COentryApp, CWinApp)
//{ {AFXJMSGJMAP (COentryApp)
ON_COMMAND ( ID_APP_ABOU , OnAppAbout )
// NOTE - the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see in these blocks of generated code
//} }AFXJMSGJMAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp: :OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp: :OnFileOpen)
// Standard print setup command
ON_COMMAND(ID_FILEJPRINT_SETUP, CWinApp: :OnFilePrmtSetup) ENDJMESSAGEJMAP ( ) i 1i/iCiOieinitiriyiAipipiiicoinisiitrmuctmionmmmmim mm mm minimum
COentryApp : : COentryApp ( )
{
// TODO: add construction code here,
// Place all significant initialization in Initlnstance
}
II The one and only COentryApp object COentryApp theApp,-
///////////////////////////////////////////////////////////////////////////// // COentryApp initialization
BOOL COentryApp : : Initlnstance ( )
{
// Standard initialization
// If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need.
Enable3dControls () ;
LoadΞtdProfileSettings () ; // Load standard INI file options (including
// Register the application's document templates. Document templates // serve as the connection between documents, frame windows and views.
CSingleDocTemplate^ pDocTemplate; pDocTemplate = new CSingleDocTemplate (
IDR_MAINFRAME,
RUNTIMEJLASS (COentryDoc) ,
RUNTIMEJ2LASS (CMainFrame) , // main SDI frame window
RUNTIMEJZLASS (COentryView) ) ; AddDocTemplate (pDocTemplate) ,-
// create a new (empty) document
OnFileNewO ,- if (m lpCmdLine[0] != '\0')
{
// TODO: add command line processing here
} return TRUE;
}
///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog
{ public :
CAboutDlg ( ) ;
// Dialog Data
//{ {AFXJDATA (CAboutDlg) enum { IDD = IDD_ABOUTBOX } ; //}}AFXJDATA
CFont m_title_font ,-
// Implementation protected: virtual void DoDataExchange (CDataExchange♦ pDX) ,- // DDX/DDV support
// { {AFX_MSG (CAboutDlg) virtual BOOL OnlnitDialog ( ) ;
//} }AFXJMSG
DECLARE MESSAGE MAP 0
}; ~
CAboutDlg : : CAboutDlg ( ) : CDialog (CAboutDlg : : IDD)
// { {AFX_DATA_INIT (CAboutDlg) //} }AFX_DATA_INIT
void CAboutDlg: : DoDataExchange (CDataExchange^ pDX) CDialog : : DoDataExchange (pDX) ;
// { {AFX_DATA_MAP (CAboutDlg) // } }AFX_DATA_MAP
BEGIN_MESSAGE_MAP (CAboutDlg, CDialog)
// { {AFX_MSG_MAP (CAboutDlg)
//}}AFX_MSG_MAP END_MESSAGE_MAP ( )
// App command to run the dialog void COentryApp : :OnAppAbout 0
{
CAboutDlg aboutDlg ; aboutDlg . DoModal ( ) ,-
} III I lllll/lll/llll/l/l/ll/lll 1111/11/ I////II/III/I // COentryApp commands
BOOL CAboutDlg: : OnlnitDialog ( )
{
CDialog: : OnlnitDialog 0 ;
LOGFONT If; memset (Self, 0, sizeof (LOGFONT) ) ,- strcpy (If . IfFaceName, "Monotype Corsiva") ,- lf.lfHeight = 24; m_title_font .CreateFontlndirect (Self) ;
GetDlgltem (IDCJABOUT1) ->SetFont (Sem_title_font )
return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE
// oentry . h : main header file for the OENTRY application
// ttdefine MINJDLY 0 ttdefine MAXJDLY 5000 ttdefine MIN_AUTO 2 ttdefine MAX_AUTO 6000 ttdefine MIN_POLL 1 ttdefine MAX_POLL 100 ttifndef AFXWIN_H__ tterror include 'stdafx.h' before including this file for PCH ttendif ttinclude "resource. h" // main symbols
///////////////////////////////////////////////////////////////////////////// // COentryApp: • .
// See oentry. cpp for the implementation of this class // class COentryApp : public CWinApp
{ public:
COentryApp 0 ;
// Overrides
// ClassWizard generated virtual function overrides
// { (AFXJVIRTUAL (COentryApp) public : virtual BOOL Initlnstance 0 ,-
//} }AFX_VIRTUAL
// Implementation
//{ {AFX_MSG (COentryApp) afx_msg void OnAppAbout ( ) ;
// NOTE - the ClassWizard will add and remove member functions h // DO NOT EDIT what you see in these blocks of generated code
//} }AFX_MSG
DECLARE MESSAGE MAP 0
};
/////////////////////////////////////////////////////////////////////////////
// OPDLG . cpp : implementation file // ttinclude " stdafx . h" ttinclude " oentry . h" ttinclude "OPDLG . h" ttifdef JDEBUG ttdefine new DEBUG_NEW ttundef THIS_FILE static char THISJFILE [] = FILE ,- ttendif extern int g_options_run ;
1 m/ OmPDLmG dmiamlogmmmiinmmminmmmiimimmiimimmiiii
OPDLG: :OPDLG (CWnd♦ pParent /=NULL+/)
: CDialog (OPDLG: :IDD_0_DLG, pParent)
// { {AFX_DATA_INIT (OPDLG)
// NOTE: the ClassWizard will add member initialization here //} }AFX_DATA_INIT
void OPDLG: : DoDataExchange (CDataExchange^ pDX)
{
CDialog: : DoDataExchange (pDX) ,- // { {AFX_DATA_MAP (OPDLG)
// NOTE: the ClassWizard will add DDX and DDV calls here //} }AFX DATA MAP
BEGIN_MESSAGE_MAP (OPDLG, CDialog)
// { {AFX_MSG_MAP (OPDLG)
//} }AFX_MSG_MAP END_MESSAGE_MAP ( )
///////////////////////////////////////////////////////////////////////////// // OPDLG message handlers void OPDLG: :OnOK() g_options_run = 40; // Re-enable the options call button this->DestroyWindow () ,- CDialog: :OnOK() ,-
User: root Host : bunny Class : bunny Job: stdin
// OPDLG . h : header file //
///////////////////////////////////////////////////////////////////////////// // OPDLG dialog class OPDLG : public CDialog
{
// Construction public :
OPDLG (CWnd^ pParent = NULL); // standard constructor
// Dialog Data
// { {AFX_DATA (OPDLG) // enum { IDD = IDDJDPJDLG } ;
// NOTE: the ClassWizard will add data members here
//} }AFXJDATA
// Overrides
// ClassWizard generated virtual function overrides
//{ {AFXJVIRTUA (OPDLG) protected: virtual void DoDataExchange (CDataExchange pDX) ; // DDX/DDV support
//} }AFXJVIRTUAL
// Implementation protected:
// Generated message map functions
//{ {AFX_MSG (OPDLG) virtual void OnOK ( ) ;
//} }AFX_MSG
DECLARE MESSAGE MAP ( )
}; ~~
User : root Host: bunny Class : bunny Job: stdin
// OptDlg . cpp : implementation file // ttinclude " stdafx . h" ttinclude " oentry . h" ttinclude "OptDlg . h"
ttifdef JDEBUG ttdefine new DEBUG JNEW ttundef THISJFILE static char THIS_FILE [] = FILE ; ttendif
extern int g_options_run ,- miimmiiiiimi mm mmiiiiiiiii/ mm mmiiiiiiim ii
II OptDlg dialog
OptDlg: :OptDlg (CWnd^ pParent /♦=NULLi/) : CDialog (OptDlg: : IDD, pParent)
// { {AFX_DATA_INIT (OptDlg)
// NOTE: the ClassWizard will add member initialization here //} }AFX DATA INIT
} " ~ void cptDlg: : DoDataExchange (CDataExchange pDX)
{
CDialog: : DoDataExchange (pDX) ;
// { {AFX_DATA_MAP (OptDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
// } }AFXJDATAJMAP
Figure imgf000424_0001
///////////////////////////////////////////////////////////////////////////// // OptDlg message handlers void OptDlg: :OnDone ()
{ g_options_run = 40 ; // Re-enable the options call button this->DestroyWmdow ( ) ;
void OptDlg -. : OnDestroy ( ) g options run = 40; // Re-enable the options call button
CDialog: :OnDestroy() ; } int OptDlg: :OnCreate (LPCREATESTRUCT IpCreateStruct)
{ if (CDialog: :OnCreate (IpCreateStruct) == -1) return -1; g_options_run = 1; // Start return 0 ;
// OptDlg. h : header file //
///////////////////////////////////////////////////////////////////////////// // OptDlg dialog class OptDlg : public CDialog
// Construction public :
OptDlg (CWnd^ pParent = NULL); // standard constructor
// Dialog Data
//{ {AFXJDATA (OptDlg) // enum { IDD = IDDJDPTIONSJDLG } ;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
// { {AFXJVIRTUAL (OptDlg) protected: virtual void DoDataExchange (CDataExchange pDX) ,- // DDX/DDV support
//} }AFXJVIRTUAL
// Implementation protected:
// Generated message map functions
IpCreateStruct);
Figure imgf000426_0001
// ( {NOJDEPENDENCIES } }
// Microsoft Developer Studio generated include file.
// Used by oentry. re
// ttdefine IDD_ABOUTBOX 100 ttdefine IDD_OENTRY_FORM 101 ttdefine IDRJMAINFRAME 128 ttdefine IDR_OENTRYTYPE 129 ttdefine IDI_ICON_Q 130 ttdefine IDB_BITMAPTEST 131 ttdefine IDD_DBDLG 133 ttdefine IDDJDJDLG 138 ttdefine IDR_3DIMES 145 ttdefine IDR_3DMDS 146 ttdefine IDIJICONJTRASH 147 ttdefine IDI_IC0N_TRASH1 148 ttdefine IDI_WAIT0 149 ttdefine IDIJWAIT1 150 ttdefine IDIJWAIT2 151 ttdefine IDI_WAIT3 152 ttdefine IDI_FILL0 153 ttdefine IDI_FILL1 154 ttdefine IDI_FILL2 155 ttdefine IDIJWAIT4 156 ttdefine IDI_WAIT5 157 ttdefine IDI_WAIT6 158 ttdefine IDCJAUTOB 1000 ttdefine IDC_EXITB 1001 ttdefine IDCJDRDERB 1002 ttdefine IDCJCUST 1003 ttdefine IDC_ITEM 1004 ttdefine IDC_QTY 1005 ttdefine IDC_PICT 1006 ttdefine IDC_COLORB 1006 ttdefine IDC_GENERIC1 1007 ttdefine IDC_TPS_EB 1008 ttdefine IDC_TRANB 1010 ttdefine IDCJOOLORBOX 1011 ttdefine IDC_LOGO_Q 1012 ttdefine IDC_ABORTB 1013 ttdefine IDCJCOMMITB 1014 ttdefine IDC_TOTALR 1015 ttdefine IDCJMSGS 1015 ttdefine IDC_SHOWDB 1016 ttdefine IDC_TPS 1017 ttdefine IDC_QUE 1018 ttdefine IDCJDLYMIN 1019 ttdefine IDC_DLYMAX 1020 ttdefine IDC_PLACER 1021 ttdefine IDC_AUTOMAX 1021 ttdefine IDC_PLACENOQR 1022 ttdefine IDC_AUTOMIN 1022 ttdefine IDC_QUELAB 1023 ttdefine IDC_POLLMAX 1023 ttdefine IDC_CUSTLAB 1024 ttdefine IDC_POLLMIN 1024 ttdefine IDC_ITEMLAB 1025 ttdefine IDC_QTYLAB 1026 ttdefine IDC_SENDREPC 1028 ttdefine IDC RECIPT 1029 ttdefine IDC FILLDB 1030 ttdefine IDC RECIPTS 1031 ttdefine IDC MSGS LAB 1032 ttdefine IDC RECIPTS LAB 1033 ttdefine IDC FILLR3 1034 ttdefine IDC DB 10 1038 ttdefine IDC DB QO 1039 ttdefine IDC DB SALEST 1040 ttdefine IDC DB SALES 1041 ttdefine IDC DB BOX 1042 ttdefine IDC DB REFILL 1043 ttdefine IDC ORDERS ITEMS 1044 ttdefine IDC Til 1045 ttdefine IDC T12 1046 ttdefine IDC T13 1047 ttdefine IDC T21 1048 ttdefine IDC T22 1049 ttde ine IDC DB PO 1050 ttdefine IDC T23 1051 ttdefine IDC ORDERBOX 1052 ttdefine IDC FILLTXT 1054 ttdefine IDC AUTOBOX 1055 ttdefine IDC dmd 1057 ttdefine IDC POLL BOX 1057 ttdefine IDC TRANBOX 1058 ttdefine IDC WAITO 1060 ttdefine IDC WAIT1 1061 ttdefine IDC OPTIONSB 1063 ttdefine IDC FILLO 1064 ttdefine IDC FILL1 1065 ttdefine IDC DB 11 1066 ttdefine IDC FILL2 1066 ttdefine IDC DB Ql 1067 ttdefine IDC DB PI 1068 ttdefine IDC DLY EB 1068 ttdefine IDC DB 12 1069 ttdefine IDC DLY SLD 1069 ttdefine IDC DB Q2 1070 ttdefine IDC DLY LAB 1070 ttdefine IDC DB P2 1071 ttdefine IDC AUTO EB 1071 ttde ine IDC DB 13 1072 ttdefine IDC AUTO SLD 1072 ttdefine IDC DB Q3 1073 ttdefine IDC AUTO LAB 1073 ttdefine IDC DB P3 1074 ttdefine IDC FILLBOX 1074 ttdefine IDC DB 14 1075 ttdefine IDC COLOR 1075 ttdefine IDC DB Q4 1076 ttdefine IDC POLL EB 1076 ttdefine IDC DB P4 1077 ttdefine IDC POLL SLD 1077 ttdefine IDC DB 15 1078 ttdefine IDC POLL LAB 1078 ttdefine IDC DB Q5 1079 ttdefine IDC DB P5 1080 ttdefine IDC CLRSTATS 1080 ttdefine IDC ABOUT1 1081 ttdefine IDC ORACREATE 1081
ttdefine IDC_BIG_TITLE 1082 ttdefine IDC_MODEBOX 1083 ttdefine IDC_STATBOX 1084 ttdefine IDC_FILLR 2000 ttdef ine IDCJTOTALS 2001
// Next default values for new obj ects
// ttifdef APSTUDIO_INVOKED ttifndef APSTUDIO_READONLY_SYMBOLS ttdefine _APS_3D_C0NTR0LS 1 ttdefine _APS_NEXT_RESOURCE_VALUE 140 ttdefine _APS_NEXT_COMMAND_VALUE 32771 ttdefine _APS_NEXT_CONTROL_VALUE 1085 ttdefine _APS_NEXT_SYMED_VALUE 101 ttendif ttendif
// stdafx.cpp : source file that includes just the standard includes
// oentry. pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information ttinclude " stdafx . h"
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
// ttinclude <afxwin.h> // MFC core and standard components ttinclude <afxext.h> // MFC extensions
// admindlg.cpp -. implementation file //
ttinclude "stdafx.h" ttinclude "qman.h" ttinclude "admindlg .h" ttdefine Q_LIB ttinclude "qlib.h" ttinclude "qadmin.h" ttinclude "rt.h" ttdefine ADMTIMER 102 extern IpSMBUFH smjnase; extern QADMSTATS g_s[3]; extern CString g_que[3] ; extern lpQHANDLE QS[3] ; int IDC_APICS[8] = { IDC_QN0NE1 , IDCJQDOWN1 , IDC_QSTOPl , IDC_QN0PUT1 , IDCJQNOGET1, ID enum pics (QNONE, QDOWN, QSTOP, QNOPUT, QNOGET, QUP, QNOPG, QFULL} ,- extern int g_pic [3+3+3] ,-
QADMCTLS g_ad; ttifdef JDEBUG ttundef THIS_FILE static char BASEDJDODE THIS_FILE[] = FILE ; ttendif
extern CFont g_text font; int ALL_TEXT_A[] = JlDCJSTATS, IDCJOGROUP, IDCJSGROUP,
IDC_PUTC, IDC_GETC, IDCJHALTC, IDC_SRESETC, IDC_FRESETC, IDCJnD
IDC_MAXSIZE, IDC_LIMLAB, IDC QSIZE,
IDOK, IDC_SET, IDC_REFRESH, θ ;
lllll III I III I II III II I II CAdminDlg dialog
CAdminDlg: : CAdminDlg (CWnd* pParent /*=NULL*/) : CDialog (CAdminDlg :: IDD, pParent)
// { fAFXJDATAJINIT (CAdminDlg)
// NOTE: the ClassWizard will add member initialization here //}}AFX DATA INIT
} " _ void CAdminDlg: : DoDataExchange (CDataExchange* pDX)
CDialog: :DoDataExchange (pDX) ; // { {AFXJDATAJMAP (CAdminDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here // } }AFXJDATAJMAP
)
Figure imgf000433_0001
///'/////'////// 1 II lllll I III lllll II II II II I III 11 III III I III mi II 11 II CAdminDlg message handlers void CAdminDlg: : SetDisplay (int init) ( CString sp, sg, s , tl , t2 ,- if (init) ( tl = g_que [m_id] + " Status"; t2 = g_que [m_id] + " Settings";
SetDlgltemText ( IDCJDGROUP, tl) ; SetDlgltemText (IDC_SGROUP,t2) ;
CListBox* lb = (CListBox*) GetDlgltem (IDC_STATS) ,- lb->ResetContent 0 ; s . Format ( "%5d committed entries" , g_s [m_id] . committed_entries) lb->InsertStri s . Format ( "%5d uncommitted puts", g_s [m_id] .pending_puts) ,- lb->Insertsr-ά s . Forma ( "%5d uncommitted gets", g_s [m_id] .pending_gets) ; lb->InsertS ) s . Format ( "%5d holes", g_s [m_id] . holey_entries) ; lb->InsertStri s . Format ( "%5d max entries", g_s [m_id] .max_entries) ; lb- >InsertStri sg = ctime (&g_s [m_id] . first_start_time) ; sp = ctime (&g_s [m_id] . last_restart_time) ,- s. Format ("%5d restarts" ,g_s [m_id] .num_restarts) ; lb- >InsertString ( -1 , s. Format ("Last restart time %s" , LPCTSTR (sg .Left (24 ))) ; lb->InsertString (-1, s. Format ("First restart time %s" , LPCTSTR (sp. Left (24 )) ) lb->InsertString (-1,
if (init) { s . Format ("( %d limit) ", g_s [m_id] .max_entries_limit) SetDlgltemText (IDCJLIMLAB, LPCTSTR (s) ) ,-
SetDlgltemlnt (IDC QSIZE, g s [m id] .max_entries) ,- i ~
// Select a icon
// if (init) // for (int i=0;i<6;i++) // if (i != g_pic [m_id] ) // GetDlgltem (IDC_APICS [i] ) >ShowWindow (SW HIDE)
if ( (g_pic [m_id] != g_pic [m_id+3+3] ) ) {
GetDlgltem (IDC_APICS [g_pic [m_id] ] ) ->ShowWindow (SW_SHOW) ,- GetDlgltem (IDC_APICS [g_pic [m_id+3+3] ] ) ->ShowWindow (SW_HIDE) g_pic [m_id+3+3] = g_pic [m_id] ;
// Set check box items if ( init ) (
( (CButton *) GetDlgltem (IDC_GETC) ) ->SetChec (g_s [m_id] .qget_state) ;
( (CButton *) GetDlgltem (IDCJPUTC) ) ->SetCheck (g_s [m_id] .qput_state) ,-
( (CButton *) GetDlgltem (IDC_SRESETC) ) ->SetCheck (g_ad. stats_reset_flag)
( (CButton * ) GetDlgltem ( IDCJFRESETC) ) - >SetCheck (g_ad . full_reset_flag) ;
((CButton *) GetDlgltem (IDC_HALTC) ) ->SetCheck (g_ad. halt_flag) ,-
} }
BOOL CAdminDlg: : OnlnitDialog ()
CDialog: : OnlnitDialog ( ) ; g_pic [m_id+3+3] = QNONE; // history is invalid for (int i=0 ,- i<6 ,- i++) // Turn all pics off.
GetDlgltem (IDC_APICS [i] ) ->ShowWindow (SWJHIDE) ,- SetDisplay (1) ;
SetTimer (ADMTIMER, 1000, NULL) ; // 1 sec
i = 0 ; whi le (ALL_TEXT_A [ i ] )
GetDlgl tem (ALLJTEXT_A [ i++ ] ) - >SetFont ( &g_text_f ont ) ;
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
} void CAdminDlg: :OnRefresh()
{
SetDisplay (1) ;
}
DWORD SetCtl (LPVOID m id)
{ int id = (int)m_id;
QsendAndReceive (QS [id] , ADMINREQ_MODE,QADM_SET_CONTROLS, 0, sizeof (g_ad) , (char return (0) ,-
void CAdminDlg: : OnSet () memset (&g_ad, 0, sizeof (g_ad) ) ; if (IsDlgButtonChecked(IDC_PUTC) ) g_ad.enable_qputs_flag++ ; if (IsDlgButtonChecked(IDCjGETC) ) g_ad.enable_qgets_flag++; if (IsDlgButtonChecked(IDC_SRESETC) ) g_ad. stats_reset_flag++; if (IsDlgButtonChecked(IDC_FRESETC) ) g_ad. full_reset_flag++;
if (IsDlgButtonChecked(IDC_SHUTDOWNC) ) g_ad. shutdown_f lag++ ; if (IsDlgButtonChecked(IDC_HALTC) ) g_ad. halt_f lag++ ; int qs = GetDlgltemlnt (IDC_QSIZE, NULL, TRUE) ; if ( (qs>0) &&(qs<=g_s [m_ιd] .max_entrιes_lιmιt ) ) g_ad.max_entrιes_value = qs ;
DWORD id;
CreateThread (NULL, 0, (LPTHREAD_STARTJROUTINE) SetCtl, (LPVOID) m_ιd,0,&ιd) ; // QsendAndReceive (QS [m_ιd] , ADMINREQ_MODE, QADM_SET_CONTROLS , 0, sizeof (g_ad) , ( if (g_ad. shutdown_f lag) { ~ g_pιc [m_ιd] = QDOWN, SetDisplay (0) , // 0=refresh only.
}
Sleep(lOOO) ,
SetDisplay (0) , // 0=refresh only.
Sleep(lOOO) , if (g_ad. shutdown_flag) CDialog : :OnOK () ; // Exit g_ad . stats_reset_flag = 0; g_ad. full_reset_flag = 0; g_ad. shutdown_flag = 0; g_ad. halt_f lag = 0,
SetDisDlay (1) ; // l=ιnιt. set buttons } void CAdminDlg: :OnEdιtchangeQsιze ( )
{ mt qs = GetDlgltemln (IDC_QSIZE, NULL, TRUE) , if ( I ( (qs>0) && (qs<=g_s [m_ιd] . max_entrιes_lιmιt ) ) ) SetDlgltemText (IDC__QSIZE, "") ,
void CAdminDlg: :OnTιmer (UINT nIDEvent) if (nIDEvent == ADMTIMER) SetDisplay (0) ,- else CDialog: :OnTιmer (nIDEvent ) ;
void CAdminDlg. : OnRButtonDown (UINT nFlags, CPoint point)
{
GetParentFrame () ->SetMessageText (" ") ; this->Invalidate 0 ;
CDialog: : OnRButtonDown (nFlags, point) ; // admmdlg h header file //
///////////////////////////////////////////////////////////////////////////// // CAdminDlg dialog class CAdminDlg public CDialog
{
// Construction public
CAdminDlg (CWnd* pParent = NULL), // standard constructor
// Dialog Data
//{ (AFXJDATA (CAdminDlg) enum { IDD = IDD_ADMINDIALOG } ,
// NOTE the ClassWizard will add data members here //} }AFXJDATA mt m_ιd,
// Overrides
// ClassWizard generated virtual function overrides //( (AFXJVIRTUAL (CAdminDlg) protected virtual void DoDataExchange (CDataExchange* pDX) , // DDX/DDV support //} }AFX_VIRTUAL void SetDisplay ( t 1),
// Implementation protected
// Generated message map functions
CPoint point),
Figure imgf000436_0001
// datadlg.cpp : implementation file // ttinclude "stdafx.h" ttinclude "qman.h" ttinclude "datadlg.h" ttinclude "KeySearch.h" ttdefine QJLIB ttmclude "qlib.h" ttinclude "qadm .h" ttmclude "rt.h" ttmclude "orderfm.h" extern lpQHANDLE QS[3]; extern QADMSTATS g_s[3] ; extern CStrmg g_que[3] ; ttifdef _DEBUG ttundef THIS_FILE static char BASEDJDODE THISJFILE [] = FILE ; ttendif i IiIiCidiaiitaiDmlgidmiamlogmmmmmiimmmmmimiimimii/m/iiii/ii
CdataDlg: : CdataDlg (CWnd* pParent /*=NULL*/) : CDialog (CdataDlg :: IDD, pParent)
{
//( (AFXJDATA_INIT(CdataDlg)
// NOTE: the ClassWizard will add member initialization here //} }AFX_DATA_INIT
void CdataDlg: : DoDataExchange (CDataExchange* pDX)
CDialog: : DoDataExchange (pDX) ; // ( (AFXJDATAJMAP (CdataDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here // } }AFX_DATA_MAP
Figure imgf000437_0001
SMBUF m; void CdataDlg: : Screenlnit 0 {
mt l, gotsize, pOFORM po = (pOFORM) &m. mdata, if (m_sub_mode == QADM_REQ_COM_DATA) s. Format ("%s %4d Commited %20d Uncommited entries" , LPCTSTR (g_que [m_ιd" g_s [m_ιd] .commιtted_entrιes, g_s [m_ιd] .pendmg_gets + g_s [m id] . ^ ι else s.Format("%s %4d Uncommited %20d Commited entries ", LPCTSTR (g_que [m_ιd] ) , g_s [m_ιd] .pendmg_gets + g_s [m_ιd] .pendmg_puts, g_s [m_ιd] . commιtted_ent SetDlgltemText ( IDCJTITLE, LPCTSTR (s) ) ;
CListBox* lb = (CListBox*) GetDlgltem ( IDCJDATAL) , lb- >ResetContent ( ) , for (ι = 0, l < 200, ι++) { *m. mdata = l, if (QSUCCESS == QsendAndReceive (QS [m_ιd] , ADMINREQJMODE, m_sub_mode ,
0 , sizeof (mt) , m mdata, sizeof (m. data) , m mdata, kgotsize , &m msgh)) ss = "%3d\t%s\t%s\t%s", if (gotsize == sizeof (OFORM) ) { s Format (LPCTSTR(ss) , l , po- >cust , po->ιtem, po- >qty, 0) , lb->InsertStrιng(-l, s) , } else if (gotsize) ( s. Format ("%3d -\t%s" , ι,m. mdata) , lb->InsertStrιng (-1, s) , } else ( break, }
} } ttdefine FORMATNAME "c.\\q\\formats.txt" cnar * IsAddr(char *c) ( mt off = 0; if (strstr (c, "msgh") ) ( if (strstr (c, "size" ) ) return((char *)m. msgh. size) ; } else if (strstr (c, "mdata") ) { sscanf (c, "%* [" []\ [%d",off) ; return ( (m. mdata + off)) ;
} return (0) ;
typedef struct fmts ( // Thread parameters void* testa, mt testv,
Figure imgf000438_0001
} FMTS, *pFMTS, void clearfmtt pFMTS p) { p->testa = NULL, p->testv = 0; *p->fmt = 0, for (mt ι=0,ι < 10;i++) p->a[ι] = NULL,
p->ne t = 0 }
FMTS fmts, void ParseFormats ( ) ( char line [LINESIZE] , char test [LINESIZE] , char format [LINESIZE] , char ops [LINESIZE] , char opl [LINESIZE] , char op2 [LINESIZE] , char op [LINESIZE) ,
FILE *fp = fopen (FORMATNAME, "r") , if ( ' £p ) (
// Say ("Cant open the data formats file %s" , FORMATNAME) , return, ) while (fgets (line, LINESIZE, fp) ) ( if ( 3 == sscanf (line, "%[",],%[",],%[",]", test, format, ops) ) { if (strchr (test , '#') ) continue, if ( 3 '= sscan (test , "%s %s %s ' , opl, op, op2) ) continue, if (strstr (opl, "size ') ) fmts testa = &m msgh size, sscanf (op2, "%d" , Scfmts testv) , strcpy (fmts fmt , format),
} else (
, //Say ( "ReadParms Ignoring %s' ,lιne),
} if (ferror(fp) ) {
// Fail ('read error in parameters file %s" , PARMNAMF) , clearerr ( p) ,
I close ( p) , )
///////////////////////////////////////////////////////////////////////////// // CdataDlg message handlers
BOOL CdataDlg OnlnitDialog ( )
(
CDialog OnlnitDialog () , m_sub_mode = QADM_REQ_COM_DATA, ((CButton *) GetDlgltem ( IDC_CMT) ) -oSetCheck (TRUE) ,
Screenlnit () , return TRUE, // return TRUE unless you set the focus to a control // EXCEPTION OCX Property Pages should return FALSE void CdataDlg OπRefreslib ( )
(
Screenlnit () ,
void CdataDlg: :OnCmt 0 m_sub_mode = QADMJREQ_COM_DATA; Screenlnit ( ) ;
void CdataDlg : : OnUncmt ( ) m_sub_mode = QADM_REQ_UNCOM_DATA; Screenlnit ( ) ,-
void CdataDlg: :OnSearchb()
CKeySearch d; d.m_id = m_id; d. DoModal 0 ,-
// datadlg.h . header file //
II Cdat iaDimlg dmiamlogmmmmmiii/immmiiiii n i n /mn m class CdataDlg : public CDialog
{
// Construction public :
CdataDlg (CWnd* pParent = NULL); // standard constructor
// Dialog Data
// { (AFX_DATA (CdataDlg) enum ( IDD = IDD_DATADIALOG } ;
// NOTE: the ClassWizard will add data members here //} }AFXJDATA int m_ιd; int m_sub_tnode ; void Screenlnit () ; // Overrides
// ClassWizard generated virtual function overrides
//( {AFXJVIRTUAL (CdataDlg) protected: virtual void DoDataExchange (CDataExchange* pDX) ,- // DDX/DDV support
//} }AFXJVIRTUAL
// Implementation protected.
// Generated message map functions
//( (AFXJMSG (CdataDlg) virtual BOOL OnlnitDialog 0 ; afx_msg void OnRefreshbO ;
;
Figure imgf000441_0001
// KeySearch.h : header file //
///////////////////////////////////////////////////////////////////////////// // CKeySearch dialog class CKeySearch : public CDialog
{
// Construction public :
CKeySearch (CWnd* pParent = NULL); // standard constructor //void CM_switch (int mode); // Dialog Data
//( (AFXJDATA (CKeySearch) enum ( IDD = IDD_KEYSEARCH } ,-
// NOTE: the ClassWizard will add data members here // } } FX_DATA //int m_min_int , m__max_int , m_at_int ; //CS ring m_min_str, m_max_str, m__at_str; int m_id; // 1-3 mt m_preds; int m_predjcype [3] ; int m_pic; int m_committed; int m_uncommitted; int m_total_entries ; int m_search_type ,- void OnCompChange (int pred); void ChangePredView (int pred, int act); void Copylnput (int pred, int min, int max);
// Overrides
// ClassWizard generated virtual function overrides
//( (AFXJVIRTUAL (CKeySearch) protected: virtual void DoDataExchange (CDataExchange* pDX) ; // DDX/DDV support
//}}AFXJIRTUAL
// Implementation protected:
// Generated message map functions //( (AFXJMSG (CKeySearch) virtual BOOL OnlnitDialog 0 ; afx_msg void OnSearchb ( ) ,- afx_msg void OnAndl ( ) ,- afx_msg void 0nAnd2 ( ) ,- afx_msg void OnSelchangeCompCbl i afx_msg void OnSelchangeCompCb2 ( 1 afx_msg void 0nSelchangeCompCb3 ( ) afx_msg void OnEditchangeMmCbl ( ) afx_msg void 0nEditchangeMinCb2 afx_msg void 0nEditchangeMinCb3 ( ) afx_msg void OnEditchangeMaxCbl ( ) afx_msg void 0nEditchangeMaxCb2 ( ) afx_msg void 0nEditchangeMaxCb3 ( ) afx_msg void OnTimer (UINT nIDEvent)
(UINT nFlags, CPoint point);
Figure imgf000443_0001
/ / mainfrm . cpp : implementation of the CMainFrame class // ttinclude " stdafx . h " # include " qman . h " ttinclude "mainfrm . h" ttifdef JDEBUG ttundef THIS_FILE static char BASED_CODE THIS_FILE [ ] = FILE ; ttendif
// CMainFrame
IMPLEMENTJDYNCREATE (CMainFrame, CFrameWnd)
BEGINJMESSAGEJMAP ( CMainFrame , CFrameWnd) //{ (AFXJMSGJMAP (CMainFrame)
// NOTE - the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see in these blocks of generated code ON WM_CREATE ( ) //J}AFXJMSGJMAP END_MESSAGEJMAP ( ) III lllll llll II 11 mimiimiu/iiii/i
I / arrays of IDs used to initialize control bars
// toolbar buttons - IDs are command buttons static UINT BASED CODE buttons [] =
{
// same order as in the bitmap 'toolbar.bmp'
IDJFILE_NEW,
ID_FILE_OPEN,
ID_FILE_SΛVE,
ID_SEPARATOR , IDJEDITJTUT , IDJEDITJCOPY , ID_EDIT_PASTE ,
ID_SEPARATOR , IDJFILEJPRINT , ID APP ABOUT ,
}; " " static UINT BASED CODE indicators [] =
{
IDJ3EPARAT0R, // status line indicator
ID_INDICAT0RJCAPS, ID_INDICATOR_NUM, ID INDICATOR SCRL,
} /////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction
CMainFrame : : CMainFrame ( )
{
// TODO: add member initialization code here
CMainFrame : . "CMainFrame ( )
{
} int CMainFrame: : OnCreate (LPCREATESTRUCT IpCreateStruct) if (CFrameWnd: :OnCreate (IpCreateStruct) == -1) return -1, if ( !m_wndToolBar. Create (this) ||
!m_wndToolBar.LoadBιtmap (IDRJMAINFRAME) | | ! m_wndToolBar . SetButtons (buttons , sizeof (buttons) /sizeof (UINT) ) )
{
TRACEO ("Failed to create toolbar\n"), return -1; // fail to create }
/* Derek's remove tool bar */ m_wndToolBar . ShowW dow (SW_HIDE) , if ( !m_wndStatusBar . Create (this) ||
! _wndStatusBar . Setlndicators ( indicators , sizeof (indicators) /sizeof (UINT) ) )
{
TRACEO ( "Failed to create status bar\n"), return -1, // fail to create }
// TODO: Delete these three lines if you don't want the toolbar to // be dockable m_wndToolBar.EnableDockmg(CBRSJALIGNJANY) ; EnableDockmg(CBRS_ALIGN_ANY) ,- DockControlBar (&m_wndToolBar) ,-
// TODO: Remove this if you don't want tool tips m_wndToolBar. SetBarStyle (m_wndToolBar .GetBarStyle () |
CBRSJΓOOLTIPS | CBRS_FLYBY) , return 0 ; }
III I II llll Illlll 11 III 111/11 I 11 /III II /Ill/Ill II III/
I / CMainFrame diagnostics ttifdef JDEBUG void CMainFrame .: AssertValid 0 const
{
CFrameWnd .AssertValid () ,
} void CMainFrame :: Dump (CDumpContextSc dc) const
CFrameWnd- :Dump(dc) ; } ttendif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMainFrame message handlers
// mainfrm . h : interface of the CMainFrame class
//
///////////////////////////////////////////////////////////////////////////// class CMainFrame : public CFrameWnd
{ protected: // create from serialization only
CMainFrame ( ) ;
DECLARE_DYNCREATE (CMainFrame)
// Attributes public :
// Operations public :
// Overrides
// ClassWizard generated virtual function overrides //{ (AFXJVIRTUA (CMainFrame) //} }AFXJVIRTUAL
// Implementation public : virtual ~CMainFrame ( ) ; ttifdef JDEBUG virtual void AssertValid ( ) const; virtual void Dump (CDumpContextk dc) const; ttendif protected: // control bar embedded members CStatusBar m_wndStatusBar; CToolBar m_wndToolBar ;
// Generated message map functions protected:
//{ (AFX_MSG (CMainFrame) afx_msg int OnCreate (LPCREATESTRUCT IpCreateStruct);
// NOTE - the ClassWizard will add and remove member functions h // DO NOT EDIT what you see in these blocks of generated code //} }AFXJMSG DECLARE MESSAGE MAP ( )
>; "
/////////////////////////////////////////////////////////////////////////////
User: root Host : bunny Class : bunny Job: stdin
// KeySearch cpp implementation file // ttmclude " stdafx h " ttmclude " qman h" ttinclude " KeySearch h" ttdef ine QJLIB ttinclude "qlib h" ttinclude " qad h " ttinclude " orderf h" ttinclude " rt h"
tt ifdef JDEBUG ttdef ine new DEBUG_NEW ttundef THISJFILE static char THISJFILE [ ] = FILE , ttendif ttdefine KEYTIMER 106 extern lpQHANDLE QS[3], extern QADMSTATS g_s[3], extern CString g_que[3], extern IpSMBUFH smjbase, extern int g_pιc [3+3+3] , mi III nn ii ii i ill III mmmmimiiiiiii i ii ii 111 III // 1 ii nil i i/imiiiii ttdefine ID_OBJS 9 mt IDCJKPICS [8] = ( IDCJ2NONE1 , IDC_QDOWNl , IDC_QSTOPl , IDCJQNOPUT1 , IDCjQNOGETi T enum IDTYPΞ ( COMP, MIN, AT, MAX, AND, OPA, OPB, OPC, OPD} , mt g_ld[3] [IDJ3BJS] = ( ( IDC_C0MP_CB1 , IDC_MIN_CB1 , IDCJAT_CB1 , IDC_MAX_CB1 , IDC_A j IDC_COMP_CB2 , IDC_MIN_CB2 , IDC_AT_CB2 , IDC_MAX_CB2 , IDC_A { IDC_COMP_CB3 , IDC_MIN_CB3 , IDC_AT_CB3 , IDC_MAX_CB3 , IDC_A
// List of items to get big fonts extern CFont gjtext font, int ALLJTEXTJ≤π = JlDC_ALL_R, IDC_COM_R, IDCJUNCOM_R, IDCJMODE, IDOK, IDSEARCHB, IDC_
///////////////////////////////////////////////////////////////////////////// // CKeySearch dialog
CKeySearch CKeySearch (CWnd* pParent /*=NULL*/) CDialog (CKeySearch IDD, pParent)
//{ (AFX_DATA_INIT (CKeySearch)
// NOTE the ClassWizard will add member initialization here //} }AFX DATA INIT
void CKeySearch DoDataExchange (CDataExchange* pDX)
{
CDialog DoDataExchange (pDX) , //( (AFXJDATAJMAP (CKeySearch)
// NOTE the ClassWizard will add DDX and DDV calls here //} }AFX DATA MAP
BEGINJMESSAGEJMAP (CKeySearch, CDialog) //{ {AFXJMSGJMAP (CKeySearch) ONJBN_CLICKED ( IDSEARCHB , OnSearchb) ONJBN_CLICKED(IDC_ANDl, OnAndl) ON_BN_CLICKED ( IDC_AND2 , OnAnd2 )
ON_CBN_SELCHANGE ( IDC_COMP_CBl , OnSelchangeCompCbl) ON_CBN_SELCHANGE ( IDC_C0MP_CB2 , OnSelchangeCompCb ) ON_CBN_SELCHANGE ( IDC_COMP_CB3 , 0nSelchangeCompCb3 ) ON_CBN_EDITCHANGE ( IDC_MIN_CB1 , OnEditchangeMmCbl ) ON_CBN_EDITCHANGE ( IDC_MIN_CB2 , OnEdιtchangeMmCb2 ) ON_CBN_EDITCHANGE ( IDC_MIN_CB3 , OnEdιtchangeMmCb3 ) ON_CBN_EDITCHANGE (IDCJMAX_CB1 , OnEditchangeMaxCbl) ON_CBNJEDITCHANGE ( IDC_MAX_CB2 , OnEdιtchangeMaxCb2 ) ON_CBN_EDITCHANGE ( IDC_MAX_CB3 , OnEdιtchangeMaxCb3 ) ONJWMJTIMER ( )
ONJBN_CLICKED(IDC_ALLJR, OnAllR) ON_BN_CLICKED(IDCjCOMJR, OnComR) ON_BN_CLICKED ( IDC_UNCOM_R, OnUncomR) ON WMJRBUTTONDOWN ( ) //J } FXJMSGJMAP
END_MESSAGE_MAP ( )
///////////////////////////////////////////////////////////////////////////// // CKeySearch message handlers
BOOL CKeySearch: : OnlnitDialog ()
{
CDialog: : OnlnitDialog ( ) ; mt l, id; m_preds = 1 , m_pred_type [ 0 ] = m_pred_type [ 1 ] = m_pred_type [ 2 ] = INT_SEARCH_TYPE , for (id = l; id < OPA; ιd++)
GetDlgltem (g_ιd[0] [id] ) ->EnableWιndow (FALSE) ; m_pιc = (g_pιc [m_ιd] + 1) % 8 ;
((CButton *) GetDlgltem ( IDC_ALL_R) ) ->SetCheck (TRUE) ; m_search_type = SEARCH_ALL_ENT ,- n_commιtted = -1; m_uncommιtted = -1; m_total_entrιes = -1;
SetDlgltemText (IDCJMODE, "View " + g_que [m_ιd] + " Entries" ) ,-
SetTimer (KEYTIMER, 1000, NULL) ; // 4 sec
1 = 0; whi1e (ALL_TEXT_S [l ] )
GetDlgltem (ALL_TEXT_S [ι++] ) ->SetFont (&gjtext_font ) ;
return TRUE, // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE
mt Strιng2Tιme ( const char *s ) ( // Thu Nov 30 17 : 30 : 00 1995 char mon [ 80 ] , mt mday, hr , mn , sc , yr , args , tm TM ,
// If it starts with a day skip it. sscanf (s, "%s " , mon) , if (strstr ("Mon Tue Wed Thu Fri Sat Sun", on)) s = s + 4 ; args sscanf (s, o o ad %d: rd : %d d" , mon, kmday, &hr , &mn, &sc , &yr) if ( ! strcmp (mon, "Jan" TM . tm_mon 0, else ( ! strcmp (mon, "Feb" TM . tm_mon 1 else ( ! strcmp (mon, "Mar" TM . tm_mon 2 else ( ! strcmp (mon, "Apr" TM . tm_mon 3 else ( ! strcmp (mon, "May" TM . tm_mon 4 else ( ! strcmp (mon, "Jun " TM . t _mon 5 else ( ! strcmp (mon, "Jul" TM . tm_mon 6 else ( ! strcmp (mon, "Aug" TM . t _mon 7 else ( ! strcmp (mon, "Sep" TM. tm_mon else ( ! strcmp (mon, "Oct" TM . tm_mon 9, else ( ' strcmp (mon, "Nov" TM . tm_mon 10, else ( ! strcmp (mon, "Dec" TM . tm mon ii; else TM tm mon = 12; if ((args == 6) && (TM tm_mon '= 12)) (
TM.tm_sec = sc,
TM.tm_mm = ran;
TM.tmJnour = hr,
TM.tm_mday = mday,
TM.tm_year = yr - 1900,
TM. tm_ιsdst = -1, return (mktime (&TM) ) ; } else return ( -1) ,
void Tιme2Strmg ( t time, char *s, t prmtday) ( if (prmtday) strcpy (s, ctime ( (ti ejt*) (&tιme) ) ) ; else strcpy (s, (ctime ( (timejt*) (&tιme) ) + 4) ) ,- // dont print day s[strlen(s) - 1] = 0; } void CKeySearch: : OnCompChange (mt pred) ( CString type_str,-
GetDlgltemText (g_ιd[pred] [COMP] ,type_str) ; t comptype = INTJ3EARCHJTYPE ,- if (type_str == "String") comptype = STR_SEARCHJTYPE ; if (type_str == "Short") comptype = SHORT_SEARCHJTYPE , m_pred_type [pred] = comptype;
CComboBox * CBat = (CComboBox *) thιs->GetDlgItem (g_ιd [pred] [AT] ) ; CComboBox * CBmm = (CComboBox *) thιs->GetDlgItem (g_ιd [pred] [MIN]); CComboBox * CBmax = (CComboBox *) this- >GetDlgItem (g_ιd [pred] [MAX] ) ;
CBat->ResetContent () , CBmm->ResetContent ( ) , CBmax- >ResetContent ( ) ; CBmm- >AddStnng ( " " ) ,
CBmm- >AddSt ring ( CBmm >AddStnng( ANY") CBmax- >AddStrιng ( ") , CBmax- >AddStrιng ( ") , CBmax- >AddStrιng ( ANY") if (type_str == "Time") ( char tim [80] ,
Tιme2Stπng (SHAREDATA (time) tim, 0) CBat->AddStπng("TIME") ,
CBmin- >SetCurSel (-1) , CBmin- >SetWmdowText (tim) , // CBmιn->ReplaceSel (tim) ,
CBmin- >AddStrmg (tim) , // add to edit box too'5
CBmax- >AddStrmg (tim) , // add to edit box too"5 else if (comptype == STRJSEARCHJTYPE) {
CBat->AddStπng( "CUSTOMER") ,
CBat- >AddStnng(" ITEM") ,
CBat->AddStπng ( " to_server" ) ,
CBat->AddStπng(' tojlogical") , else if (comptype == INT_SEARCH JTYPE) {
CBat->AddStrιng("UID" ) ,
CBat->AddStrιng( "TID") ,
CBat->AddStrmg("HOST") ,
CBat->AddStrmg( "QUANTITY") ,
IpRT rt = RTROOT, while (rt = NextRT(rt)) {
CBmm- >AddString (RTJNODE(rt) ) , CBmax- >AddStπng (RT NODE(rt) ) ,
} else if (comptype == SHORT_SEARCH_TYPE) { CBat->AddStnng("MODE") , CBat->AddStrmg("SUBJMODE") ,
for (int id = 1, id < ID_OBJS, ιd++)
GetDlgltem (g_ιd [pred] [id] ) ->EnableWιndow (TRUE) , GetDlgltem (IDSEARCHB) ->EnableWmdow (TRUE) ,
// GetParentFrame 0 ->SetMessageText ("") , cedit SetDlgltemText ( IDC_SERSTAT, "") ,
((CComboBox *) this- >GetDlgItem (g_ιd [pred] [AT] ))- >SetCurSel (0) , ((CComboBox *) this- >GetDlgItem (g_ιd [pred] [MAX] )) ->SetCurSel (0) ((CComboBox *) this- >GetDlgItem (g_ιd [pred] [MIN] ))- >SetCurSel (0)
} void CKeySearch OnSelchangeCompCbl () {OnCompChange ( 0 ) void CKeySearch OnSelchangeCompCb2 () (OnCompChange (1) void CKeySearch .0nSelchangeCompCb3 () [ OnCompChange ( 2 ) void CKeySearch ChangePredView (mt pred, int act)
{ t id, for (id = 0, id < ID OBJS , ιd++)
GetDlgltem (g_ιd [pred] [id] ) ->ShowWιndo (act ) , for (id = 1, id < 0PA, ιd++)
GetDlgltem (g_ιd [pred] [id] ) - >EnableWmdow (FALSE) , if (act == SWJHIDE) for (id = 0, id < AND, ιd++)
((CComboBox *) thιs->GetDlgItem (g_ιd [pred] [id] ) ) ->SetCurSel ( -1) , if (act == SWJHIDE ) { // Get rid of the ghost of the combo box MFC bug' this- >Invalιdate ( ) , thιs->UpdateWιndow ( ) ,
CKeySearch OnAndl ( ) if (m preds == 1) {
ChangePredView ( 1 , SW_ _SH0W) m preds = 2 , else {
ChangePredVie ( 1 , SW_ HIDE)
ChangePredView (2 , SW~ _HIDE) m preds = 1 ,
void CKeySearch OnAnd2() if (m_preds == 2) ( ChangePredView (2, SW_SHOW) , m_preds = 3 , } else {
ChangePredView; 2, SWJHIDE) , m preds = 2 ,
void CKeySearch Copylnput ( int pred, int from, int to)
{
CString s, int pos,
GetDlgltemText (g_ιd [pred] [from],s GetBuffer (100) , 100) , s .ReleaseBuffer ( ) , pos (CComboBox *) thιs->GetDlgItem (g_ιd [pred] [to] ) ) - >GetCurSel ( )
( (CComboBox *) thιs->GetDlgItem(g_ιd[pred] [to] ) ) ->DeleteStrmg (0) , ( (CComboBox * ) thιs->GetDlgItem(g_ιd[pred] [to] ) ) - >InsertStrιng (0 , s) , ( (CComboBox *) thιs->GetDlgItem(g_ιd[pred] [from] ) ) - >DeleteStrmg (1) , ( (CComboBox *) thιs->GetDlgItem(g_ιd[pred] [from] ) ) -> Inserts t ring (1, s) if (pos == 0) ( (CComboBox *) thιs->GetDlgItem(g_ιd[pred] [to] ) ) ->3etCurSel (0) ,
} void CKeySearch . OnEditchangeMmCbl ( ) Copylnput (0, MIN, MAX) void CKeySearch .OnEdιtchangeMmCb2 () Copylnput (1, MIN, MAX) void CKeySearch .OnEdιtchangeMmCb3 () (Copylnput (2, MIN, MAX) void CKeySearch OnEditchangeMaxCbl 0 f Copylnput (0, MAX, MIN) void CKeySearch OnEdιtchangeMaxCb2 () (Copylnput (1, MAX, MIN) void CKeySearch :OnEdιtchangeMaxCb3 () (Copylnput (2, MAX, MIN) void CKeySearch: :OnSearchb ( )
(
SMBUF b,B; QADMSEL key; OFORM order;
CString ss , s , at_str , mιn_str , max_str; lnt ι,at_mt, sz, matches;
GetDlgltem (IDSEARCHB) ->EnableWmdow (FALSE) ,
CListBox* lb = (CListBox*) GetDlgltem ( IDC_SEARCH_LB) ; lb->ResetContent () ,-
SetDlgltemText (IDC_SERSTAT, "") ;
// lb->SetTabStops (100) ; key . num_preds = m_preds; key . search__type = m_search_type ; // SEARCHJALL_ENT for (int p = 0; p < m_preds ,- p++ ) {
// Set mm and max values mm_str = " " ; max_str = " " ;
GetDlgltemText (g_ιd[p] [MIN] , mm_str . GetBuffer (100) ,100) ;
GetDlgltemText (g_ιd[pϊ [MAX] , max_str . GetBuffer ( 100) ,100) ;
GetDlgltemText (g_ιd [p] [AT] , at_str . GetBuffer (100 ) ,100) ; mm_str . ReleaseBuffer ( ) ; max_str .ReleaseBuffer () ; at_str. ReleaseBuffer ( ) ,- at_ t = GetDlgltemlnt (g_id[p] [AT] , NULL, TRUE) , strcpy (key. preds [p] . mm_str_val , LPCTSTR (mιn_str) ) ; strcpy (key. preds [p] .max_str_val , LPCTSTR (max_str) ) ,- key. preds [p] .mm_mt_val = GetDlgltemlnt (g_ιd [p] [MIN] , NULL, TRUE) ; // mm I key. preds [p] .max_mt_val = GetDlgltemlnt (g_ιd [p] [MAX] , NULL, TRUE) , // max I key. preds [p] .mm_sh_val = key .preds [p] . mm_ιnt_val ; // mm short key. preds [p] .max_sh_val = key. preds [p] .max_ιnt_val ; // max short
if (mm_str == "ANY") { key .preds [p] .mιn_switch = 0; key. preds [p] .min_str_len = 0; } else { key .preds [p] .mm_swιtch = 1 ; key .preds [p] .mm_str_len = strlen (key .preds [p] .min str val); } if (max_str == "ANY") ( key. preds [p] .max_swιtch = 0; key. preds [p] .max_str_len = 0; } else ( key .preds [p] .max_switch = 1 ; key .preds [p] .max_str_len = strlen (key .preds [p] .max_str_val) ;
if (at_str == "TIME") { char tim [80] ; if (max str == "NOW")
key .preds [p] .max_mt_val = SHAREDATA (time) ; if ( d = Strιng2Tιme (LPCTSTR (max_str) ) ) <= -1) key .preds [p] .max_mt_val = 1, if (mm_str == "NOW") key .preds [p] .mm_mt_val = SHAREDATA (time) ; if ( d = Strmg2Tιme (LPCTSTR (mιn_str) ) ) '= -1) key .preds [p] .mm_ιnt_val = l,
// Tιme2Strmg (key .preds [p] . mm_ιnt_val , tim, 1) , // s Format ("Time value : %s ", tim) , // SetDlgltemText (IDC_SERSTAT,s) ,
if (at_str == "HOST") ( if (l = Name2IP (LPCTSTR (max_str) ) ) key. preds [p] .max_mt_val = l, if (l = Name2IP (LPCTSTR (mm_str) ) ) key . preds [p] .mm_mt_val = l,
// Find the offset if (at_str = == "TIME") at_ιnt = (char *) Scb msgh. time) (char *) Scb.msgh) , if (at_str : "MODE") at_ιnt = (cnar *) Scb msgh. mode) (char *) Scb msgh) if (at_str - "SUBJMODE") at_ιnt : (char *) Scb.msgh sub_mode) (char *) &b.msgh) if (at_str = "UID") at_ιnt = (char *) Scb.msgh mid uid) (char *) &b msgh) if (at_str = "TID") at_ιnt = (char *) Scb msgh. mid tid) (char *) Scb.msgh) if (at_str = "HOST") at_ιnt = (char *) ϋb.msgh. mid. host) (char *) Scb.msgh) if (at_str = "SIZE") at_mt = (char *) Scb msgh. size) (char *) Scb msgh) ; if (at_str = " to_server" ) at_ιnt : (char *) Scb.msgh. to_server) (char *) Scb. msgh) , - if (at_str : "tojlogical" ) at_mt = (char *) Scb.msgh to logical) (char *) Scb.msgh) , if (at_str = == "CUSTOMER") at_ιnt = = sizeof (MSGH) + ( (char *) Scorder cust) - ( (char *) Scorder) ; if (at_str • == "ITEM") at t : = sizeof (MSGH) + ((char *) Scorder item) - ((char *) Scorder) , if (at_str == "QUANTITY") at t = sizeof (MSGH) + ( (char *) Scorder.qty) - ((char *) Scorder) ,
key. preds [p] .offset = at_mt, key. preds [p] .predjtype = m_pred_type [p]
// Get the list of key matches if (QSUCCESS == QsendAndReceive (QS [m_ιd] , ADMINREQJMODE, QADMJREQ_SEL_DATA,
0, sizeof (key) , (char *) Sckey, sizeof (b mdata), b mdata, &sz, Scb msgh") { lpMID md = (lpMID) b mdata, matches = sz / sizeof (MID), if (matches > 0) ( char * h = IP2Name (md- >host) , for (I = 0, l < matches , ι++) ( ss Format ( "%s (%d, %d) " , IP2Name (md- >host ) , md- >uιd, md- >tιd) , s Forma ("%4d \t%s",ι+l,ss ), lb- >InsertStrmg ( -1 , s) , md = (lpMID) ( (char * ) md + sizeof (MID) ) ,
} else { lb- >InsertStrmg ( - 1 , "No messages " ) ,
lb- >UpdateWmαow ( ) , //Sleep ( 200 ) , md = (lpMID) b mdata, lpOFORM po = (lpOFORM)B mdata, for (I = 0, l < matches , ι++) { memcpy (B mdata, md, sizeof (MID) ) , // Copy one mid s Format("%d Messages Reading %d" , matches , l) , SetDlgltemText ( IDC_SERSTAT, s) , GetDlgltem (IDC_SERSTAT) - >UpdateWmdow ( ) , if (QSUCCESS == QsendAndReceive (QS [m_ιd] , ADMINREQJMODE, QADM_REQJMSG , 0 , sizeof (mid) , B mdata, sizeof (B mdata), B mdata, Scsz, ScB msgh)) ( ss Format ("%s (%d, %d) " , IP2Name (md->host ) , md->uιd, md- >tιd) , if (B msgh. size == sizeof (OFORM) ) s Format("%4d \t%s\t% -8s\t%2d %-10s",ι + 1 , ss , po->cust , po->qty, po else if (sz) s Format("%4d \t s\t%s",ι + 1 , ss , b .mdata) , else s Format ("%4d \t%s\t<<Empty>> " , I + l,ss), lb->DeleteStrmg (l) , lb->InsertStrιng d, s) , } else { s Format ("%d Error requesting %s(%d,%d)",ι + 1 , IP2Name (md->host ) , md- SetDlgltemText ( IDCJ3ERSTAT, s) , break, // Stop here
} md = (lpMID) ( (char * ) d + sizeof (MID) ) ,
} else s Format ( "Error - no reply") , if ( 'strstr (LPCTSTR (s) , "Error") ) s Format ( "%d Matches ",matches),
SetDlgltemText ( IDC_SERSTAT, s) ,
Sleep(500) ,
GetDlgltem (IDSEARCHB) - >EnableWmdow (TRUE) ,
void CKeySearch..OnTimer (UINT nIDEvent)
{ if (nIDEvent == KEYTIMER) ( int com, uncom, CString s, i f ( (g_pιc [m_ιd] ' = m_pιc ) ) (
GetDlgl tem ( IDCJKPICS [g_pιc [m_ιd] ] ) - >ShowWιndow ( SW_SHOW) GetDlgl tem ( IDCJKP ICS [m_pιc ] ) - >ShowWmdow ( SW_HIDE ) , m_pιc = g_pιc [m_ιd] ,
// Set Title this- >SetWmdowText ( "View " + g_que [m_ιd] ),
if (m_commιtted '= (com = g_s [m_ιd] . commιtted_entrιes) ) { s Forma ("%3d Committed entries ", (m_commιtted = com)), SetDlgltemText (IDC_COM_R, s) , if (m_uncommιtted '= (uncom = g_s [m_ιd] .pendmg_gets + g_s [m_ιd] pending p s . Format ( "%3d Uncommitted entries ", (m_uncommιtted = uncom)), ~ SetDlgltemText (IDC UNCOM R,s),
} " if (m_total_entrιes '= (com + uncom)) ( s .Format ( "All %d entries ", (m_total_entrιes = com + uncom)), SetDlgltemText (IDC_ALL_R, s) ;
} else
CDialog. : OnTimer (nIDEvent) ,
void CKeySearch: :OnAllR()
{ m_search_type = SEARCH_ALL_ENT,- } void CKeySearch :: OnComR ( )
( m_search_type = SEARCH_COMJENT , } void CKeySearch: -OnUncomR ()
{ m_search_type = SEARCHJUNCOM_ENT; } void CKeySearch: : OnRButtonDown (UINT nFlags, CPoint point)
{
GetParentFrame ( ) - >SetMessageText ( " " ) ; thιs->Invalιdate () ,-
CDialog .OnRButtonDown (nFlags , point), // qman cpp Defines the class behaviors for the application // ttinclude "stdafx h" ttinclude "qman h" ttinclude " a frm h" ttinclude "qmandoc h" ttinclude "qmanview h" ttifdef JDEBUG ttundef THIS_FILE static char BASED_CODE THISJFILE [] FILE ttendif
Figure imgf000458_0001
BEGINJMESSAGEJMAP ( CQmanApp , CWinApp )
// ( (AFXJMSGJMAP (CQmanApp)
ON_COMMAND ( ID_APP_ABOU , OnAppAbout )
// NOTE - the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see in these blocks of generated code
//) }AFXJMSGJMAP
// Standard file based document commands
ONJCOMMANDdDJFILEJNEW, CWinApp OnFileNew)
ON_COMMAND(IDJFILE_OPEN, CWinApp OnFileOpen)
// Standard print setup command
ON_COMMAND(ID_FILEJPRINT_SETUP, CWinApp OnFilePrmtSetup) ENDJMESSAGE_MAP ( ) nn mmimimiiiimiiimiiiiiii i in 11 iiiiiiiiim
I I CQmanApp construction
CQmanApp CQmanApp ( )
{
// TODO add construction code here,
// Place all significant initialization m Initlnstance }
///////////////////////////////////////////////////////////////////////////// // The one and only CQmanApp object
CQmanApp theApp,
///////////////////////////////////////////////////////////////////////////// // CQmanApp initialization
BOOL CQmanApp Initlnstance ( )
{
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
Enable3dControls 0 ,
LoadStdProflleSettmgs () , // Load standard INI file options (including
// Register the application's document templates Document templates
// serve as the connection between documents, frame windows and views
CSmgleDocTemplate* pDocTemplate , pDocTemplate = new CSmgleDocTemplate (
IDRJMAINFRAME,
RUNTIME_CLASS (CQmanDoc) ,
RUNTIME_CLASS (CMainFrame) , // mam SDI frame window
RUNTIMEJCLASS (CQmanView) ) , AddDocTemplate (pDocTemplate) ,
// create a new (empty) document OnFileNe O , if (m lpCmdLinefO] '= '\0')
{
// TODO add command line processing here
} return TRUE,
} iiiimm i m i ii imm mmimim iiiiiiiiiimi nn iimmim
I I CAboutDlg dialog used for App About class CAboutDlg public CDialog
{ public
CAboutDlg () ,
// Dialog Data
//{ (AFXJDATA (CAboutDlg) enum { IDD = IDD_ABOUTBOX } , //} } AFXJDATA
CFont m_tιtle_font , // Implementation protected virtual void DoDataExchange (CDataExchange* pDX) , // DDX/DDV support
//( (AFXJMSG (CAboutDlg) virtual BOOL OnlnitDialog () ,
//} }AFX_MSG
DECLARE_MESSAGE_MAP ( )
CAboutDlg CAboutDlg 0 CDialog (CAboutDlg IDD)
//{ (AFX_DATA_INIT (CAboutDlg) // } }AFX_DATAJINIT
void CAboutDlg DoDataExchange (CDataExchange* pDX)
CDialog DoDataExchange (pDX) , // ( (AFXJDATAJMAP (CAboutDlg) // } }AFX_DATA_MAP
BEGINJMESSAGEJMAP (CAboutDlg, CDialog)
//{ (AFX_MSGJMAP (CAboutDlg) „„„ ..„
U0U4D t
// } } AFXJMSGJMAP ENDJMESSAGEJMAP ( )
/ / App command to run the dialog void CQmanApp : : OnAppAbout ( )
{
CAboutDlg aboutDlg; aboutDlg . DoModal ( ) ; }
///////////////////////////////////////////////////////////////////////////// // CQmanApp commands
BOOL CAboutDlg: : OnlnitDialog ()
(
CDialog: : OnlnitDialog ( ) ,-
LOGFONT If; memset (Self, 0, sizeof (LOGFONT) ) ; strcpy (If . IfFaceName, "Monotype Corsiva") ; lf.lfHeight = 24; m_title_font . CreateFontlndirect (Self) ;
GetDlgltern ( IDCJABOUT1) ->SetFont (&m_title_font ) ,-
// TODO: Add extra initialization here return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE
// qman h main header file for the QMAN application // ttifndef AFXWINJH tterror include ' stdaf h' before including this file for PCH ttendif ttmclude "resource h" // mam symbols
/////////////////////////////////////////////////////////////////////////////
// CQmanApp
// See qman cpp for the implementation of this class
// class CQmanApp public CWinApp
{ public
CQmanApp ( ) ,
// Overrides
// ClassWizard generated virtual function overrides
//{ (AFXJVIRTUAL (CQmanApp) public virtual BOOL Initlnstance () ,
//} }AFXJVIRTUAL
// Implementation
// ( {AFX_MSG (CQmanApp) afx_msg void OnAppAbout ( ) ,
// NOTE - the ClassWizard will add and remove member function // DO NOT EDIT what you see in these blocks of generated coue
//} }AFXJMSG
DECLARE MESSAGE MAP ( )
mimmmimmmmmmmiiiiimiii nm nn mmmmiimi/iii
// qmandoc . cpp : implementation of the CQmanDoc class // ttinclude " stdafx . h" ttinclude " q an . h" ttinclude " qmandoc . h" tt ifdef JDEBUG ttundef THISJFILE static char BASED_CODE THISJFILE [ ] = FILE ; ttendif immnmmmimmmmmmmmmmminmimmiiiniiimi
I I CQmanDoc
IMPLEMENTJDYNCREATE (CQmanDoc , CDocument )
BEGINJMESSAGEJMAP (CQmanDoc , CDocument) // { {AFXJMSGJMAP (CQmanDoc)
// NOTE - the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see in these blocks of generated code //} }AFXJMSGJMAP ENDJMESSAGEJMAP ( )
III lllll II 11/1111 III II III! Ill/ III II III I lllll I III 11 II nn II//II II CQmanDoc construction/destruction
CQmanDoc : : CQmanDoc ( )
{
// TODO: add one-time construction code here
CQmanDoc : : "CQmanDoc ( )
{ }
BOOL CQmanDoc : : OnNewDocument ( )
{ if ( ! CDocument : : OnNewDocument ( ) ) return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document) return TRUE; }
///////////////// /////////////////////////////////////////// ///////////////// // CQmanDoc serial ization void CQmanDoc : -. Serialize (CArchiveSc ar)
{ if (ar . IsStoring O )
{
/ / TODO : add storing code here
} else
/ / TODO : add loading code here
///////////////////////////////////////////////////////////////////////////// // CQmanDoc diagnostics ttifdef JDEBUG void CQmanDoc : : AssertValid ( ) const
{
CDocument : : AssertVal id ( ) ;
} void CQmanDoc : -.Dump (CDumpContextSc dc) const
{
CDocument : :Dump(dc) ;
} ttendi f / /JDEBUG IIIII III mmmmm/iiiiii nm III ii nm mm/mi mmmi
I I CQmanDoc commands
/ / qmandoc . h : interface of the CQmanDoc class //
III / mmmnm/mmmimmiiiimiii iimmmiimm mimi/iiii class CQmanDoc : public CDocument
{ protected: // create from serialization only
CQmanDoc ( ) ;
DECLAREJDYNCREATE (CQmanDoc)
// Attributes public :
// Operations public :
// Overrides
// ClassWizard generated virtual function overrides
//( (AFXJVIRTUAL (CQmanDoc) public : virtual BOOL OnNewDocument () ;
//} }AFXJVIRTUAL
// Implementation public : virtual "CQmanDoc 0; virtual void Serialize (CArchiveSc ar) ; // overridden for document i/o ttifdef JDEBUG virtual void AssertValid ( ) const; virtual void Dump (CDumpContextSc dc) const; ttendif protected :
// Generated message map functions protected :
// ( (AFXJMSG (CQmanDoc)
// NOTE - the ClassWizard will add and remove member functions h // DO NOT EDIT what you see in these blocks of generated code //} }AFXJMSG DECLARE MESSAGE MAP ( )
}; "
/////////////////////////////////////////////////////////////////////////////
// qmanview h interface of the CQmanView class
//
///////////////////////////////////////////////////////////////////////////// class CQmanView public CFormView
( protected // create from serialization only
CQmanView ( ) ,
DECLAREJDYNCREATE (CQmanView) public
//{ (AFXJDATA (CQmanView) enum( IDD = IDDJQMANJFORM },
// NOTE the ClassWizard will add data members here //} }AFXJDATA
// Attributes t m_maxtrack, CString m_que[3], public
CQmanDoc* GetDocument () ,
// Operations public
// Overrides
// ClassWizard generated virtual function overrides
// { {AFX_VIRTUAL ( CQmanVlew) public virtual void OnlnitialUpdate () , protected virtual void DoDataExchange (CDataExchange* pDX) , // DDX/DDV support virtual BOOL OnPreparePπnting (CPrmtlnfo* plnfo), virtual void OnBegmPrintmg (CDC* pDC, CPrmtlnfo* plnfo), virtual void OnEndPrmt g (CDC* pDC, CPrmtlnfo* plnfo), virtual void OnPrmt(CDC* pDC, CPrmtlnfo*), virtual void OnDrawfCDC* pDC) ,
//}}AFXJ IRTUAL //void InitTrackBar (HWND hTrack, mt IDMIN, t TMIN, t IDMAX, t TMAX, m //DWORD Poll () , //DWORD CQmanView PollO, void CQmanView . OpenQue (mt 1, t IDC_QUES) ,
// meter painting void DrawKey ( ) , void GetMeterBoxes () , void TestMeters ( ) , void CQmanView DrawMeterdnt l) , void CQmanView CmdLine ( t pass), void CQmanView DrawKeyColor ( t ID, mt HS , COLORREF COL),
// font
CFont m_tιtle_font,
// Implementation public virtual ~CQmanView ( ) , ttifdef JDEBUG virtual void AssertValid ( ) const,
virtual void Dump (CDumpContextϋ dc ) const ; ttendif protected
, CScrollBar* pScrollBar)
point),
Figure imgf000466_0001
ttifndef _DEBUG // debug version qmanview.cpp inline CQmanDoc* CQmanVie :: GetDocument ( )
{ return (CQmanDoc* ) m_pDocument ,- } ttendif i ii ii 11 IIIII nm mimiiii/i iiimiiiniminn
User: root Host : bunny Class: bunny Job: stdin
// qmanview.cpp implementation of the CQmanView class //
ttinclude "stdafx.h" ttmclude "qman.h" ttinclude " qmandoc. h" ttinclude "qmanview.h" ttinclude "admmdlg.h" //tt clude "datadlg h" ttinclude "KeySearch. h"
//+++++++++++++ QLIB +++++++++++++++++++ ttmclude "qlib.h" ttinclude "qadmm.h" ttmclude "rt.h"
ttdefine MYTIMER 100 ttαef me TITLETIMER 101 ttdefine MIN_POLL_DLY 100 ttdefine MAX POLL DLY 5000
extern IpSMBUFH sm base, lpQHANDLE QS[3] = "[NULL , NULL , NULL } ;
QADMSTATS g_s[3+3] ; // 3 Current + 3 Old
//HWND g_track[3] HWND g_tmm[3] , HWND g_tmax[3] ; HWND g_tlab[3] , CString g_que [] } int ALL TEXT[] IDCJTMIN1 , IDC_TMIN2 , IDCJTMIN3 , ' IDCJTMAX1 , IDCJTMAX2 , IDC_TMAX3 , IDC_TLAB1 , IDCJTLAB2 , IDC_TLAB3 , IDCJADMINB1 , IDC_ADMINB2 , IDC_ADMINB3 , IDCJDATABl , IDCJDATAB2 , IDC_DATAB3 , IDCJQUES1, IDCJDIJES2 , IDC_QUES3 , IDC EXIT, 0,0,0} ;
mt IDCJTMINS [] = | IDC_TMIN1 , IDCJTMIN2 , IDCJTMIN3 ; mt IDCJTMAXS [ ] = IDCJTMAX1 , IDCJTMAX2 , IDCJTMAX3 ' mt IDCJTLABSU = IDCJTLAB1 , IDCJTLAB2 , IDCJTLAB3 ' t IDC_METERS [] = ( IDC_METER1 , IDC 4ETER2 , IDCJMETER3 } ; t IDC_PICS [3] [8] = ( ( IDCJQNONE1 , IDC_QD0WN1 , IDC_QST0P1 , IDC_QN0PUT1 , IDC_QN0GET1
IDCJQN0NE , IDC_QDOWN4 , IDC_QSTOP4 , IDC_QNOPUT4 , IDC_QNOGET4 { IDCJQNONE5 , IDC_QDOWN5 , IDC_QSTOP5 , IDCJ2NOPUT5 , IDC_QNOGET5 enum pics (QNONE, QDOWN, QSTOP, QNOPUT, QNOGET, QUP, QNOPG, QFULL} ; int g_pιc [3+3+3] ,- int g_poll; int g_poll_delay = 2000, CFont g_text font;
typedef struct met ( // Thread parameters
CRect b_rec ,
CRect c_rec,
CRect p_rec;
CRect g_rec,
CRect h_rec;
CRect f_rec; mt commit , pendp, pendg, hole, free , min, max; } MET, *pMET;
MET g_met [3+4] ,
//+++++++++++++ QLIB +++++++++++++++++++
ttifdef JDEBUG ttundef THIS_FILE static char BASED_CODE THISJFILE [] FILE ttendif
///////////////////////////////////////////////////////////////////////////// // CQmanView
IMPLEMENTJDYNCREATE (CQmanView, CFormView)
lePπntPrevιew)
Figure imgf000469_0001
///////////////////////////////////////////////////////////////////////////// // CQmanView construction/destruction
CQmanView : : CQmanVie ( )
: CFormView (CQmanVie :: IDD)
//( (AFXJDATA_INIT (CQmanView)
// NOTE: the ClassWizard will add member initialization here // } }AFXJDATA_INIT // TODO: add construction code here CQmanView ~CQmanVιew()
! void CQmanView .DoDataExchange (CDataExchange* pDX)
{
CFormView. : DoDataExchange (pDX) ,- // ( (AFXJDATAJMAP (CQmanView)
// NOTE- the ClassWizard will add DDX and DDV calls here // } }AFX_DATA_MAP
///////////////////////////////////////////////////////////////////////////// // CQmanView printing
BOOL CQmanView .OnPreparePrmting (CPrmtlnfo* plnfo)
{
// default preparation return DoPreparePrmting (plnfo) ;
} void CQmanView . OnBegmPrintmg ( CDC* / *pDC* / , CPrmt lnfo* / *pInfo* / )
// TODO add extra initialization before printing } void CQmanView . . OnEndPrmt mg ( CDC* /*pDC* / , CPrmtlnfo* /*pInfo* / )
{
// TODO add cleanup after printing
} void CQmanView . . OnPrmt (CDC* pDC , CPrmtlnfo* )
{
// TODO add code to print the controls
}
///////////////////////////////////////////////////////////////////////////// // CQmanView diagnostics ttifdef JDEBUG void CQmanView: : AssertValid ( ) const
{
CFormView: :AssertValid ( ) ,-
} void CQmanView . -Dump (CDumpContextSc dc) const
{
CFormView: -. Dump(dc) ,
}
CQmanDoc* CQmanView ::GetDocument ( ) // non-debug version is mime
{
ASSERT (m_pDocument->IsKmdOf (RUNTIMEJCLASS (CQmanDoc) ) ) ; return (CQmanDoc* )m pDocument ;
} ttendif //JDEBUG
///////////////////////////////////////////////////////////////////////////// // CQmanView message handlers
void CQmanView OnExit ( )
{ g_poll = 0, // Stop the threads AfxGetMa Wnd ( ) ->DestroyWmdow ( ) ,
// METER METER METER METER METER METER METER METER METER METER METER METER // METER METER METER METER METER METER METER METER METER METER METER METER // METER METER METER METER METER METER METER METER METER METER METER METER // // b_rec // // Committ Pending holes Free // // // c rec p_rec h rec
void CQmanView GetMeterBoxes ( ) { for (int ι=0,ι<3,ι++){
GetDlgltem (IDCJMETERS [l] ) - >GetWιndowRect Ug_met [l] b rec ) // Adjust coordantates for 0,0,l,b g met ^1 b rec right g_met [ I ] b_rec lef t , g me 'l b _rec bottom g_met [ I ] b_rec top , g__met J b_ rec left g_met [ ι ] b_rec top = 0, g met ^1 c _rec left = 0, // Commit always starts at 0,0 g met 1 f~ rec right = g_met[ι] b_rec right, // Free always ends at max g met . 1 c rec top g met 'l P_ rec top g met . 1 g rec top g met J h rec top g met 1 f~ rec top g_met [I] b_rec top, // 0 g met !ι c rec bottom g met 'l p~ rec bottom g met .1 g rec bottom g met !ι h rec bottom g met !ι f" rec bottom = g_met[ι] b_rec bottom, // All the same hight
void CQmanView DrawKeyColor (mt ID, mt HS, COLORREF COL) CRect c_rec, CBrush *pCBrush, if ( HS == -1 ) pCBrush = new CBrush (COL), else pCBrush = new CBrush (HS, COL) ,
GetDlgltem (ID) - >GetWmdowRect (&c_rec) ,
// Adgust coordantates for 0,0,l,b c rec right -= c rec. left,
c_rec bottom c_rec top; c rec left c_rec . top = 0;
// The DC for the meter CDC* pCOLORDC = GetDlgltem ( ID) ->GetDC ( )
// Select this brush, save the old CBrush *pOldBrush = pCOLORDC- >SelectObπ ect (pCBrush) ,- pCOLORDC- >Rectangle (c_rec) ;
GetDlgltem (ID) -> Invalidate () , delete (pCBrush) , ReleaseDC (pCOLORDC) ,
void CQmanView . DrawKeyOf
DrawKeyColor ( IDC_KEY_COM, 1, RGB (127, 255, 255) DrawKeyColor ( IDC_KEY_PENPUT , HS_BDIAGONAL, RGB (000, 182,255) DrawKeyColor ( IDCJKEYJPENGET, HSJFDIAGONAL, RGB ( 000 , 182 , 255 ) ) DrawKeyColor (IDC_KEY_HOLE, HSJDIAGCROSS, RGB ( 255 , 128 , 128 ) )
ttdefine MAXPIXELS g_met [1] .b rec . right void CQmanView . estMeters ( ) int c,pg,pp,h, // Pixel width of each rectangle for ( t ι = 0,ι<3;ι + +) { // If any change if ( (g_met [1] . commit = g_s [ι] .commιtted_entrιes) (g_met [l] .pendg = g_s [l] .pendmg_gets ) (g_met [l] pendp = g_s [l] .pendmg_puts) (g_met [l] .hole = g_s[ι] . holey_entrιes ) | (g_met [I] free = g_s [l] .num_free_entrιes) (g_met [I] max = g_s[ι] .max_entrιes) ) { if ( 'g_s [l] .max_entrιes) g_s [l] .tnax_entnes=l , // No divide by zero
// Update old values g_met [l] . commit = g_s [l] . commιtted_entrιes , g_met [I] pendg = g_s[ι] .pendmg_gets, g_met [ι] .pendp = g_s [l] .pendmg_puts, g_met [l] hole = g_s [l] . holey_entrιes , g_met [l] free = g_s [l] . num_f ree_entπes , g_met [I] max = g_s [l] .max_entrιes,
// c,pp,pg,h,f are points on a line between mm, max scaled to ttpixels c = 0 + (MAXPIXELS * g_met [l] . commit) /g_met [l] . max, pp= c + (MAXPIXELS * g net [ι] .pendp) /g_met [l] . max, pg=pp + (MAXPIXELS * g_met [i] .pendg) /g__met [l] .max; h =pg + (MAXPIXELS * g_met [ι] hole) /g_met [l] . max;
// f = h + (MAXPIXELS * g_met [1] . free) /g_met [1] . max, // constant
// Make 5 rectangles to fill with colors // g_met [l] .c_rec.left = 0; // constant
g_met [1] c_rec right = c, g_met[ι] p_rec left = c, g_met [1] .p_rec right = pp, g_met [1] g_rec left = pp, g_met [1] g_rec right = pg, g_met[ι] h_rec left = pg, g_met [1] h_rec right = h, g_met [1] f_rec left = h,
// g_met [1] f_rec right = g_met [1] .max, // constant
DrawMeter d) ,
void CQmanView DrawMeter ( t ι){
// Create the Brush
CBrush *pCBrush = new CBrush ( RGB (127 , 255 , 255 ) )
CBrush *pPBrush = new CBrush ( HSJBDIAGONAL, RGB ( 000 , 182 , 255 ) )
CBrush *pGBrush = new CBrush ( HSJFDIAGONAL, RGB ( 000 , 182 , 255 ) )
CBrush *pHBrush = new CBrush ( HSJDIAGCROSS , RGB (255 , 128 , 128) )
// The DC for the meter CDC* pCOLORDC = GetDlgltem ( IDCJMETERS [l] )- >GetDC () ,
// Create a PEN
// CPen *pQPen = new CPen (PS_SOLID, 3 , RGB ( 0 , 0 , 255 ) ) ,
// CPen *p01dPen = pXDC->SelectObgect (pQPen) ,
// Select this brush, save the old CBrush *p01dBrush = pCOLORDC- >SelectOb] ect (pCBrush) , pCOLORDC- >Rectangle (g_met [l] c_rec) , pCOLORDC- >SelectObq ect (pPBrush) , pCOLORDC- >Rectangle (g_met [l] .p_rec) , pCOLORDC- >SelectOb] ect (pGBrush) , pCOLORDC- >Rectangle (g_met [l] g_rec) , pCOLORDC- >SelectObπ ect (pHBrush) , pCOLORDC- >Rectangle (g__met [l] h_rec) , pCOLORDC- >SelectStockObg ect (WHITEJBRUSH) , pCOLORDC- >Rectangle (g_met [l] f_rec) ,
pCOLORDC- >SelectOb] ect (ScpOldBrush) , // Reset the brush GetDlgltem (IDCJMETERS [l] ) - invalidate ( ) , delete (pCBrush) , delete (pPBrush) , delete (pGBrush) , delete (pHBrush) , ReleaseDC (pCOLORDC) ,
/ / / / / / / / // / / / /// / /// / / / ////// // / // / / // Init the track bar //
/ / 0 TPS 100 / /
// I [ ] I //
// MIN MAX //
////////////////////////////////////
void InitTrackBar (HWND hTrack, HWND HMIN, int TMIN, HWND HMAX, int TMAX) CString s;
//HWND hTrack = GetDlgltem ( ID) - >m_hWnd;
SendMessage (hTrack, TBM_SETRANGEMIN, TRUE, TMIN) ; SendMessage (hTrack, TBM_SETRANGEMAX, TRUE, MAX) ; SendMessage (hTrack, TBM_SETTICFREQ, 1 , TRUE) ; SendMessage (hTrack, TBM_SETPOS , TRUE, TMIN) ,- SendMessage (hTrack , TBM_SETSELSTART , TRUE , TMIN) // Select from start
// Track Bar lables I Is . Format ( " %d" , TMIN) ; SetDlgltemText (IDMIN, s) ; // s .Format ( "%d" , TMAX) : SetDlgltemText (IDMAX, s) ; s. Forma ("%d" ,TMIN) ; : : SendMessage (HMIN, WM_SETTEXT, 0, (LPARAM) (LPCTSTR) s) ; s. Format ("%d" ,TMAX) ,- : :SendMessage (HMAX, WM_SETTEXT, 0, (LPARAM) (LPCTSTR) s) ;
DWORD Poll (LPVOID qnum)
{
MSGH mh;
CString s,sl; int used = 1; // Clear the track bar if not in use int i = (int) (qnum) ; g_poll = 1; while (g_poll) ( if (QS[i]) ( int sz,- used++ ; if (QS [i] ->open_time)
: : SendMessage (g_tlab[i] , WM_SETTEXT , 0 , (LPARAM) (LPCTSTR) "STARTING..." if (QSUCCESS >= (QsendAndReceive (QS [i] , ADMINREQ MODE, QADMJREQ_STATS , 0, sizeof (g_s [i] ) , (char *) &g_s [i] , &sz, &mh) ) ) if ((mh.mode == ADMINREP_MODE | | mh.mode == ACK_MODE ) ScSc (sz > 0) ) {
// Note: now, mode is ADMINREPJMODE if local or if (!memcmp( Scg_s[i+3], Scg_s [i] , sizeof (QADMSTATS) )) // nothing c goto skip; memcpy( Scg_s[i+3], Scg_s [i] , sizeof (QADMSTATS) ) ; // set history
// Assign a picture if (g_s [i] . qget_state &Sc g_s [i] . qput_state) g pic [ i] = QUP ;
else if (g_s [1] .qget_state) g_pιc[ι] = QNOPUT; else if (g_s [i] .qput_state) g_pιc [1] = QNOGET, else g_pιc[ι] = QNOPG, if (g_s [1] . num_f ree_entrιes 0) g_pιc[ι] = QFULL;
if (QS [1] ->open_tιme) QS [1] - >open_time = 0, // Get rid of "START s Format ( "%s :%s at %s has %d entries ", &g_s [I] physical qname , Sg si . Format ( "%d" , g_s [l] .max_entrιes) , ~~ ~ -SendMessage (g_tlab [l] , WM_SETTEXT, 0 , (LPARAM) (LPCTSTR) s) , ..SendMessage (g_tmax[ι] , MJSETTEXT, 0 , (LPARAM) (LPCTSTR) si) , : SendMessage (g_tmιn [l] ,WM_SETTEXT, 0, (LPARAM) (LPCTSTR) "0") ,
} else { g_pιc [l] = QDOWN,
SendMessage (g_tlab[ι] ,WM_SETTEXT, 0, (LPARAM) (LPCTSTR) "BAD REPLY QS[l] = NULL, Sleep (3000) ,
} else { g_pιc [l] = QDOWN,
.SendMessage (g_tlab[ι] ,WM_SETTEXT, 0, (LPARAM) (LPCTSTR) "TIME OUT") , QS[ι] = NULL, Sleep (3000) ,
i else // No open que
// if (g_que[ι] == "") // g_pιc[ι] = QNONE, if (used) { used = 0, 11 The track bar will now be clear memset (&g_s [l] ,0, sizeof (g_s [l] ) ) ; g_s [ι+3] .max_entrιes = 1 ;
//: : SendMessage (g_track[ι] , TBM_SETPOS, TRUE, 0) ;
//: : SendMessage (g_track [l] , TBM_SETSELEND, TRUE, 0) ;
SendMessage (g_tlab[l] , WM_SETTEXT, 0 , (LPARAM) (LPCTSTR) "No Que") SendMessage (g_tmιn[l] , WM_SETTEXT, 0 , (LPARAM) (LPCTSTR) SendMessage (g_tmax[ι] , WM_SETTEXT, 0 , (LPARAM) (LPCTSTR) " " ) ,
skip. Sleep (g_poll_delay) ; } // While loop return (1) ;
void CQmanView: . CmdLine (mt pass) ( CString parm, value, line, nline ,- mt l, polyline = AfxGetApp () - >m_lpCmdLιne ,- while (2 <= (i = sscan (LPCTSTR (line) , "%s %s % [~@] " , parm.GetBuffer (100) ,value .GetBuffer (100) , nlme .GetBuffer (100 ) ) ) ) parm. MakeUpper ( ) , 000473
if (parm == "POLL") { sscanf (LPCTSTR (value) , "%d" , ϋpoll) , if ( (MIN_POLL_DLY <= poll) ScSc (poll <= MAX_POLL_DLY) ) g_poll_delay = poll,
if (parm == "1") {
CComboBox * CB = (CComboBox *) thιs->GetDlgIte ( IDCJQUES1) , CB->SelectStrmg (-1, value) , OnSelchangeQuesl ( ) , if (parm == "2") {
CComboBox * CB = (CComboBox *) this- >GetDlgItem ( IDC_QUES2 ) , CB->SelectStrmg (-1, value) , ~
0nSelchangeQues2 () , if (parm == "3") {
CComboBox * CB = (CComboBox *) this- >GetDlgIte ( IDC_QUES3 ) , CB->SelectStrιng (-1, value) , 0nSelchangeQues3 () ,
line = LPCTSTR (nline) nlme = " " ,
mt g_poll_delay_old, void CQmanView OnTimer (UINT nIDEvent)
// Select ICONS if (nIDEvent == MYTIMER) ( for (mt ι = 0,ι<3,ι++) { if (g_pιc[ι] '= g_pιc[ι+3]) {
GetDlgltem (IDC_PICS[ι] [g_pιc [l] ] ) - >ShowWmdow (SW_SHOW) , GetDlgltem (IDC_PICS [l] [g_pιc [ι + 3] ] ) - >ShowWmdow (SW_HIDE) g_pιc[ι+3] = g_pιc[ι],
TestMeters () ,
} else if (nIDEvent == TITLETIMER) { GetParentFrame () ->SetWιndowText ("QMAN" KillTimer (TITLETIMER) , DrawKey () ,
} else
CFormView OnTimer (nIDEvent ) ,
void CQmanView OnlnitialUpdate ( ) {
LOGFONT If,
CString s,
CFormView. : OnlnitialUpdate ( ) // Default from vc++
// Set frame size = Form size GetParentFrame ( ) - >RecalcLayout ( ) , ResizeParentToFit (FALSE) , ResizeParentToFit (TRUE) ,
GetMeterBoxes ( ) , DrawKey ( ) , for ( t ι=0 , ι<3 , ι++ ) {
// gjtrack[ι] = GetDlgltem ( IDCJTRACKS [l] )- >m_hWnd, g_tmm[ι] = GetDlgltem ( IDC JTMINS [l] )- >m_hWnd, g_tmax[ι] = GetDlgltem ( IDCJTMAXS [l] )- >m_hWnd, g_tlab[ι] = GetDlgl em (IDCJTLABS [l] ) ->m_hWnd, g_pιc[ι] = QNONE, // man g_pιc[ι+3] = QSTOP, // yellow
// LIST OF QUEUES
// CListBox* lb = (CListBox*) GetDlgltem ( IDC_QUE)
// lb->InsertStrιng(-l, "Ql") ,
// lb->InsertStrmg(-l, "Q2") ,
// lb->SetCurSel (0) ,
//Q = Qopen ( "Ql" , PUTTING, 0, 0, 0, 0, 0) ,
CComboBox * CB1 = (CComboBox *) this - >GetDlgItern ( IDC_QUES1 ) CComboBox * CB2 = (CComboBox *) thιs->GetDlgItem(IDC_QUES2) CComboBox * CB3 = (CComboBox *) thιs->GetDlgItem(IDC QUES3) CBl->ResetContent 0 ,- CB2->ResetContent () , CB3->ResetContent () ,
// List all logical queues
// APPS [physical] , logicall, logιcal2, [physical] , logical, if (smjcase = AttachSharedMemory ()) { IpRT rt = RTROOT, while (rt = NextRT (rt)) ( char *e,*s = RT_APPS(rt), // Starts after the first letter while (s = strchr (s, ',') ) v // Ends at next if (e = strchr (++s, ',') ) { *e = 0, if ( (!strchr(s, ' [') ) ScSc *s) ( CBl->AddStrmg(s) , // lb->InsertStrmg(-l, s) CB2->AddStnng(s) , // lb->InsertStrmg (-1, s) CB3->AddStrιng(s) , // lb->InsertStrιng ( -1, s)
} else {
GetParentFrame () ->SetMessageText ( "QNETD not running (?) please start it ") MessageBox ("QNETD not running, please start it ' , 0, MB_ICONSTOP) , //AfxGetMamWnd 0 >DestroyWmdow () ,
CBl->AddStπng("") , //CB1- >SetCurSel (1) , CB2->AddStrιng("") , //CB2->SetCurSel (1) , CB3->AddStrιng("") , //CB3 ->SetCurSel (1) ,
DWORD id,
CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) Poll, (LPVOID) 0,0, kid),
CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) Poll, (LPVOID) l,0,Scid),
CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) Poll, (LPVOID) 2,0,&ιd) ,
CmdLine (1) ,
SetTimer (MYTIMER, 250, ULL) , // 1/4 second SetTimer (TITLETIMER, 100, NULL) ,
// Fonts memset ( Self , 0 , sizeof (LOGFONT) ) , tt i fdef BIGFONT
If IfHeight = 18, ttelse
If IfHeight = 13, ttendif g_tex _ront CreateFontlndirect (Slf ) , scrcpydf IfFaceName "Matura MT Script Capitals"), strcpydf IfFaceName, "Monotype Corsiva"),
If IfHeight = 32, m_tιtle_font CreateFontlndirect (Self ) ,
GetDlgltem (IDCJTITLE) ->SetFont (Sctt_tιtle_font ) , ι = 0, while (ALL_TEXT[ι] )
GetDlgltem (ALLJTEXT [ι++] ) ->SetFont (Seg_text_font) ,
void CQmanView OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
// TODO Add your message handler code here and/or call default // CFormView OnHScroll (nSBCode , nPos, pScrollBar), // Removed by derek
void CQmanView OpenQue (mt l, mt IDCJQUES)
{
CString s,que, t sta ,
GetDlgltemText (IDC_QUES, que GetBuffer (100) , 100) ,
que ReleaseBuffer () ; if (que '= g_que[ι]) ( // the user changed the open que name GetParentFrame () ->SetWmdowText ("QMAN") ; if (que == g_pιc [l] QNONE ; g_que [ 1 ] s = "No Que will be used" ,
Qclose (ScQSti] ,0) ; } else ( g_pιc[ι] = QSTOP, s .Format ( "Opening que %s",que); memset (Scg_s [l] , 0, sizeof (QADMSTATS) ) ,
GetParentFrame () ->SetMessageText (s) ; // MessageBox (s) , causes 2nd pass if (QS[i] = Qopentque. GetBuffer (0) , PUTJMODE, 0 , Q_FAILOVER, ScStat, 0, 0) ) ( g_que [ l] = que ; s .Format ("Qopen (%s) " ,que) ; // QS [l] ->tιme_out = 1000, // 1 second
} else ( s . Format ( "Qopen (%s) Error %d" , que , stat ) ,
CComboBox * CB = (CComboBox *) this- >GetDlgItem ( IDC_QUES) ,
CB->SelectStrmg(-l, " ") ; g_que[ι] = ""; g_pιc[ι] = QDOWN,
}
GetParentFrame 0 - >SetMessageText (s)
void CQmanView. • OnSelchangeQuesl () OpenQue (0, IDCJQUES1) void CQmanView :OnSelchangeQues2 ( ) OpenQue ( 1 , IDCJQUES2 ) void CQmanView: :OnSelchangeQues3 ( ) OpenQue (2 , IDC_QUES3 ) void CallAdmdnt id) { if (QSdd)) (
CAdminDlg adm; adm.m_ιd = id; adm. DoModal 0 ,-
void CallDatadnt id) ( if (QSdd]) {
CKeySearch d, // CdataDlg d.m_ιd = id; d . DoModal ( ) ;
void CQmanView. OnAdmmbl ( ) CallAdm(O) void CQmanView: OnAdmmb2 ( ) CallAdm(l) void CQmanView: OnAdmιnb3 ( ) CallAdm(2)
void CQmanView: :OnDatabl () ( CallData(O) void CQmanView: :OnDatab2 () j CallData(l) void CQmanView: :OnDatab30 { CallData(2) void CQmanView: :OnDraw(CDC* pDC) DrawMeter (0) DrawMeter (1) DrawMeter (2) DrawKey ( ) ;
CFormView: :OnDraw(pDC) ;
// this->SetWindowText ("Qman av");
// GetParentFrame () ->SetWindowText ("QQMAN"
void CQmanView: : OnRButtonDown (UINT nFlags, CPoint point)
{
GetParentFrame ( ) - >SetMessageText ( " " ) ; this- >Invalidate ( ) ,-
CFormView: : OnRButtonDown (nFlags , point) ,-
}
User: root Hos : bunny Class: bunny Job: stdin
// buf dig . cpp : implementation f ile // ttinclude " stdafx . h" ttinclude "netman . h" ttinclude "bufdig. h"
// ttinclude "buferdlg.h"
//+++++++++++++ QLIB +++++++++++++++++++ ttdefine QJLIB ttinclude "qlib.h" ttinclude "rt.h" ttinclude "netadmin.h" ttdefine BUFTIMER 101 extern IpSMBUFH s base; extern SMBUFH g smhead; extern SMBUFH g_smhead_old ; extern CString g node ; extern int g_polling; extern int g remote node ; extern int gjpic; extern lpQHANDLE g_q; extern IpRT g rt ,-
Figure imgf000482_0001
extern int g CBufDlg state;
//+++++++++++++ QLIB ++++++++++++++++++H
ttifdef _DEBUG ttundef THIS_FILE static char BASED_CODE THISJFILE [] = FILE ; ttendif III
I I CBufDlg dialog
CBufDlg: : CBufDlg (CWnd* pParent /*=NULL*/) : CDialog (CBufDlg :: IDD, pParent)
//{ (AFXJDATAJINIT (CBufDlg)
// NOTE: the ClassWizard will add member initialization here //} }AFXJDATAJINIT
void CBufDlg: : DoDataExchange (CDataExchange* pDX) CDialog: : DoDataExchange (pDX) ;
//( { AFXJDATAJMAP ( CBufDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here //} }AFX DATA MAP
BEGIN_MESSAGEJMAP (CBufDlg, CDialog)
//( (AFXJMSGJMAP (CBufDlg)
ON_WM_TIMER ( )
ON_LBN_DBLCLK(IDC_BUFLB, OnDblclkBuflb)
ONJLBN_SELCHANGE ( IDCJBUFLB , OnSelchangeBuflb)
ONJWM_CREATE ( )
ON WM_RBUTTONDOW ( )
//7}AFX_MSGJMAP ENDJMESSAGEJMAP ( )
II III III////////////////////////// ////////////////// /////lll/m mmiiimm II iimiiiimimimmmiimm/imiimiimiimmm
iiiiiiiiimi iiimmiimmmiiimmmmimi/miimmm
I I CBufDlg m ienss magemhamndilemrsmmmmmmmmmmmmninmmui
BOOL CBufDlg: : OnlnitDialog 0
{
CDialog: :OnInitDialog ( ) ,- return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE
int g_BufPoll = 0 ;
DWORD BufPoll (LPVOID ttype)
{ int i,type = ( int) (ttype) ,- if (g_remote_node) ( if ( ( gJBuf Pol l + + == 0 ) ScSc g_q ScSc g_rt ) {
QsendAndReceive (g_q, QNETDREQJMODE , NETMAN_SMBUFS , 0,0,0, (sizeof (BSA) ), (char *) ScgjDsa, 0 , 0) ;
} } else { // pack local data into structure lpBSA b = Scgjbsa; b->nsbuf = SHAREDATA (nsbuf) ; for (i=0; i < SHAREDATA (nsbuf) ,- i++ ) memcpy ( Scb- >bs [i] , SMBUFADDRd) , sizeof (BS) );
} gJBufPoll = 0; return (1) ;
int g_display_a_buf = 0 ,- ttdef ine BUFHS gjosa . bs [gjlbsel ] ttde f ine MSGHS g_bsa . bs [g_lbsel ] . msgh ttdef ine SHOWITEM (X) GetDlgltem ( X ) - >ShowWindow ( SW_SH0W) ; ttdef ine HIDEITEM (X) GetDlgltem (X) - >ShowWindow ( SWJHIDE ) ; void CBufDlg : : OnTimer (UINT nIDEvent )
{ if (nIDEvent == BUFTIMER) { DWORD id; int i,copy=0;; CString s ; if (g_CBufDlg_state >= 10) OnOK ( ) ,-
if ( memcmp (Seg_bsa, Scg_bsa_old, sizeof (BS) * g_bsa. nsbuf )){ copy++; // will copy memcpy (ScgJbsa_old, Scgjbsa, sizeof (BSA) ) ;
CListBox* lb = (CListBox*) GetDlgltem ( IDC BUFLB) ; lb->ResetContent () ,- for d=0; i < gjosa .nsbuf ; i++ ) { s . Format ( "%5d %d %d %s",i+l, gjbsa . bs [i] . status, gjosa . bs [i] . sub_sta lb- >InsertString ( -1 , s) ;
// g_display_a_buf 1 = init; 2 = run ; 3 = stop; switch (g_display_a_buf ) ( case 1: // run g_display_a_buf = 2; // run
SHOWITEM (IDCJDATE) ;
SHOWITEM(IDC_DATEL) ;
SHOWITEM ( IDC_MID) ;
SHOWITEM (IDCJMIDL) ;
SHOWITEM (IDC_TO) ;
SHOWITEM ( IDC_T02 ) ;
SHOWITEM ( IDCJTOL) ;
SHOWITEM ( IDC_FROM) ;
SHOWITEM (IDCJFROML) ;
SHOWITEM (IDC_PB0)
SHOWITEM(IDCJPBl)
SHOWITEM ( IDCJPB2 )
SHOWITEM ( IDCJPB3 )
SHOWITEM (IDCJPB4)
SHOWITEM ( IDCJPB5 )
SHOWITEM ( IDCJPB6 )
SHOWITEM ( IDCJPB7)
SetDlgltemText ( IDCJPB8 , g_node + "'s " + BUFHS . name + " buffer"); case 2 : // run if (memcmp (ScBUFHS, Seg_bs_old, sizeof (BS) ) ) { // some change memcpy (ScgjDs_old,ScBUFHS, sizeof (BS) ) ; if (MSGHS.time) SetDlgltemText (IDCJDATE, ctime (ScMSGHS . time) ) else SetDlgltemText (IDCJDATE, "No date");
00048 o
s. Format ("from=%s uid=%d tid=%d" , ( (char *) IP2Name (MSGHS .mid. host) ), M
SetDlgltemText (IDC_MID, s) ; s. Format ("%s %s ", MSGHS . to_server, MSGHS . tojlogical) ,-
SetDlgltemText (IDCJTO,s) ; s.Format("%s port=%d buf=%d" , IP2Name (MSGHS . to_node) , MSGHS . to_port j
SetDlgltemText (IDCJT02, s) ; ~~ s .Format ( "buffer %d (reply to buffer %d) ", MSGHS . from_smbuf , MSGHS . rep
SetDlgltemText (IDC FROM,s);
} break; case 3: // disable g_display_a_buf = 0; // off
HIDEITEM( IDCJDATE) ; HIDEITEM(IDCJDATEL) ; HIDEITEM(IDC_MID) ; HIDEITEM(IDCJMIDL) ; HIDEITEM(IDCJΓO) ,- HIDEITEM(IDC_T02) ; HIDEITEM(IDC_TOL) ; HIDEITEM(IDC_FROM) ; HIDEITEM(IDC_FROML) ; HIDEITEM(IDCJPBO) ;
HIDEITEM(IDCJPBl) ; HIDEITEM(IDCJPB2) ; HIDEITEM(IDC_PB3) ; HIDEITEM(IDC_PB4) ; HIDEITEM(IDC_PB5) ; HIDEITEM(IDC_PB6) ; HIDEITEM(IDCJPB7) ; SetDlgltemText (IDC_PB8, "Detail") ;
if ( !g_remote_node) ;
CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) BufPoll, (LPVOID) 0,0, &id)
} else {
CDialog: : OnTimer (nIDEvent) ,-
/* void CBufDlg: :OnLButtonDblClk (UINT nFlags, CPoint point)
{
// If inside the list box
CListBox * LB= (CListBox *) this->GetDlgItem ( IDCJBUFLB) ,- g_lbsel = LB- >GetCurSel ( ) ;
CBufDlg d; d. DoModal ()
// else
CDialog: :OnLButtonDblClk (nFlags , point) ,-
void CBufDlg: :OnDblclkBuflb ()
{
// CString s ,-
CListBox * LB= (CListBox *) this- >GetDlgIte ( IDCJBUFLB) g_lbsel = LB->GetCurSel ( ) ;
// Somtimes returns out-of-bounds nunmber if ( (g_lbsel >=0 ) ScSc (g_lbsel < g_bsa . nsbuf ) ) { if (strcmp (g_bsa . bs [g_lbsel] . name, "empty" ) ) { g_display_a_buf = 1; // init
// CBuferDlg d; // d. DoModal 0 ;
void CBufDlg: : OnSelchangeBuflb ()
{ if (g_display_a_buf ) g_display_a_buf = 3 ; // stop
void CBufDlσ: : OnOK ( )
{ g_CBufDlg_state = 20; KillTimer (BUFTIMER) ; this- >DestroyWindow ( ) ; //CDialog: :OnOK() ;
int CBufDlg: : OnCreate (LPCREATESTRUCT IpCreateStruct)
{ if (CDialog: :OnCreate (IpCreateStruct) == -1) return -1; this->SetWindowText (g_node + " buffers"),- memset (Scg_bsa_old, 0, sizeof (BSA) ) ;
SetTimer (BUFTIMER, 1000, NULL) ; // 1 second g_CBufDlg_state = 2; return 0;
} void CBufDlg: : OnRButtonDown (UINT nFlags, CPoint point)
{
GetParentFrame ( ) - >SetMessageText ( " " ) ; this->Invalidate () ;
CDialog: : OnRButtonDown (nFlags, point) ; }
User: root Host : bunny Class: bunny Job: std
// bufdlg h header file //
II CBufDlg dialog class CBufDlg public CDialog
{
// Construction public
CBufDl (CWnd* pParent = NULL), // standard constructor
// Dialog Data
//{ (AFXJDATA (CBufDlg) enum ( IDD = IDD_BUF_DLG } ,
// NOTE the ClassWizard will add data members here //} } AFXJDATA
// Overrides
// ClassWizard generated virtual function overrides
//( (AFXJ/IRTUAL (CBufDlg) protected virtual void DoDataExchange (CDataExchange* pDX) , // DDX/DDV support
//} }AFXJVIRTUAL
// Implementation protected
),
Figure imgf000488_0001
// buferdlg.cpp implementation file // tt clude "stdafx.h" ttmclude "netman h" ttmclude "buferdlg.h" ttdefine QJLIB ttdefine BUFFERTIMER 103 ttinclude "qlib.h" ttmclude "netadmm.h" extern CString g_node , extern BSA gjosa, extern mt gjlbsel; extern BS g_bs_old;
ttifdef JDEBUG ttundef THISJFILE static char BASED_CODE THISJFILE [] = FILE_ ttendif m II CmBumferDmlgmdimalogmmmiimimiiiiiiii mmmiiiiiimmii
CBuferDlg. -CBuferDlg (CWnd* pParent /*=NULL*/) CDialog (CBuferDlg. : IDD, pParent)
(
//{ (AFXJDATAJINIT (CBuferDlg)
// NOTE the ClassWizard will add member initialization here //} }AFX DATA INIT
vo d CBuferDlg: : DoDataExchange (CDataExchange* pDX)
{
CDialog: .DoDataExchange (pDX) ; //{ (AFXJDATAJMAP (CBuferDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here //}}AFXJDATAJMAP
BEGINJMESSAGE_MAP (CBuferDlg, CDialog)
//{ (AFXJMSGJMAP (CBuferDlg)
ON WMJTIMERO
//|}AFXJMSGJMAP ENDJMESSAGEJMAP ( )
II CBuferDlg message handlers
BOOL CBuferDlg: : OnlnitDialog 0
{
CDialog: : OnlnitDialog ( ) ,
// TODO. Add extra initialization here n,0
0υu 4o /
memset (&gJt>s_old, 0 , sizeof (BS) ) ,
SetTimer (BUFFERTIMER, 1000, NULL) , // 1 second return TRUE, // return TRUE unless you set the focus to a control // EXCEPTION OCX Property Pages should return FALSE } ttdefine BUFHS gjbsa bs [g_lbsel] ttdefine MSGHS g_bsa bs [gjlbsel] msgh ttdefine POST lb- >InsertStrmg ( -1 , s) void CBuferDlg OnTimer (UINT nIDEvent)
{ i f (nIDEvent == BUFFERTIMER) ( i f (memcmp ( SeBUFHS , SegjDS_old , s i zeof ( BS ) ) ) { / / some change memcpy ( Seg_bs_old , SeBUFHS , s izeof ( BS ) ) ,
CStrmg s , t ,
CListBox * lb= (CListBox *) this- >GetDlgItern ( IDC_BUFLB) , t = ctime (ScMSGHS time), s = "Message " + t, POST, s Format ( "Mode=%4d Sub=%4d" , MSGHS mode , MSGHS sub_mode) , POST, s Format ("MID host=%x tιd=%d" , MSGHS mid hos , MSGHS mid tid), POST, s Format ("To %x Port %d Buffer %x", MSGHS to_node , MSGHS to_port , MSGHS to s Format ("From %d Reply zo %d" , MSGHS from_smbuf , MSGHS reply_smbuf ) , POS s Format ("To physical %s logical %s", MSGHS to_server, MSGHS tojlogical thιs->SetWmdowText (g_node + "'s " + BUFHS name + " bufrer"),
} else
CDialog OnTimer (nIDEven ) ,
// buferdlg.h : header file //
///////////////////////////////////////////////////////////////////////////// // CBuferDlg dialog class CBuferDlg . public CDialog
{
// Construction public .
CBuferDlg (CWnd* pParent = NULL), // standard constructor
// Dialog Data
//{ {AFXJDATA (CBuferDlg) enum { IDD = IDDJBUFFER } ,
// NOTE: the ClassWizard will add data members here //} }AFXJDATA
// Overrides
// ClassWizard generated virtual function overrides
//{ (AFXJVIRTUAL (CBuferDlg) protected . virtual void DoDataExchange (CDataExchange* pDX) , // DDX/DDV support
//} }AFXJVIRTUAL
// Implementation protected .
// Generated message map functions
,
Figure imgf000491_0001
// mamfrm cpp . implementation of the CMainFrame class // ttinclude " stdafx . h" ttinclude " netman . h" ttinclude "mainfrm . h" ttifdef JDEBUG ttundef THIS_FILE static char BASED_CODE THISJFILE [] = FILE , ttendif
///////////////////////////////////////////////////////////////////////////// // CMainFrame
IMPLEMENTJDYNCREATE (CMainFrame , CFrameWnd)
BEGIN_MESSAGE_MAP (CMainFrame , CFrameWnd) //{ (AFXJMSGJMAP (CMainFrame)
// NOTE - the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see in these blocks of generated code ON WM_CREATE ( ) //J}AFXJMSGJMAP ENDJMESSAGEJMAP ( )
II arrays of IDs used to initialize control bars
// toolbar buttons - IDs are command buttons static UINT BASED CODE buttons [] =
{
// same order as in the bitmap 'toolbar.bmp'
ID_FILE_NEW,
ID_FILE_OPEN,
ID_FILE_SAVE,
ID_SEPARATOR, ID_EDIT_CUT, ID_EDIT_COPY, ID_EDIT_PASTE,
ID_SEPARATOR, ID_FILE_PRINT, ID APP ABOUT,
}; " " static UINT BASED_CODE indicators [] =
ID_SEPARATOR, // status line indicator
IDJINDICATOR_CAPS , ID_INDICATOR_NUM, ID INDICATOR SCRL, \ .
11/1/ I III 11 l/llll/l I ll/lll/llll/ll/l/lll II
II CMainFrame construction/destruction CMainFrame CMainFrame ( )
// TODO add member initialization code here
CMainFrame . "CMainFrame ( )
int CMainFrame . : OnCreate ( LPCREATESTRUCT IpCreateStruct )
{ if (CFrameWnd: :OnCreate (IpCreateStruct) == -1) return -1; if ( !m_wndToolBar . Create (this) | |
!m_wndToolBar.LoadBιtmap(IDRJMAINFRAME) | | !m_wndToolBar . SetButtons (buttons , sizeof (buttons) /sizeof (UINT) ) )
{
TRACEO ("Failed to create toolbar\n"); return -1; // fail to create }
/* Derek's remove tool bar */ m_wndToolBar . ShowWindow (SWJHIDE) ; if ( !m_wndStatusBar. Create (this) ||
!m_wndStatusBar . SetIndicators (indicators , sizeof (indicators) /sizeof (UINT) ) )
{
TRACEO ("Failed to create status bar\n"), return -1; // fail to create }
// TODO. Delete these three lines if you don't want the toolbar to
// be dockable m_wndToolBar . EnableDockmg (CBRS_ALIGN_ANY) ;
EnableDockmg(CBRS_ALIGNJANY) ;
DockControlBar (Scm_wndToolBar) ,-
// TODO: Remove this if you don't want tool tips m_wndToolBar . SetBarStyle (m_wndToolBar . GetBarStyle ( ) | CBRSJTOOLTIPS | CBRS_FLYBY) ; return 0 ,- }
////////////////// /////////////////////////////////////////////////////////// // CMainFrame diagnostics ttifdef JDEBUG void CMainFrame : -. AssertValid ( ) const
{
CFrameWnd: : AssertValid ( ) ,
} void CMainFrame :: Dump (CDumpContextSc dc) const
{
CFrameWnd: :Dump(dc) ;
} ttendi f //JDEBUG
///////////////////////////////////////////////////////////////////////////// // CMainFrame message handlers
// mamfrm h interface of the CMainFrame class
//
///////////////////////////////////////////////////////////////////////////// class CMainFrame public CFrameWnd
{ protected // create from serialization only
CMainFrame () ,
DECLAREJDYNCREATE (CMainFrame)
// Attributes public
// Operations public
// Overrides
// ClassWizard generated virtual function overrides //{ (AFXJVIRTUAL (CMainFrame) //} (AFXJVIRTUAL
// Implementation oublic virtual ~CMainFrame ( ) , ttifdef JDEBUG virtual void AssertValid ( ) const, virtual void Dump (CDumpContextSc dc) const, ttendif orotected // control bar embedded members CStatusBar m_wndStatusBar , CToolBar m_wndToolBar,
// Generated message map functions protected
//( (AFX_MSG (CMainFrame) afx_msg int OnCreate (LPCREATESTRUCT IpCreateStruct),
// NOTE - the ClassWizard will add and remove member functions h // DO NOT EDIT what you see m these blocks of generated code //}}AFXJMSG DECLARE MESSAGE MAP ( ) }. - -
/////////////////////////////////////////////////////////////////////////////
// netmadoc . cOp : implementation of the CNetmanDoc class // ttmclude " stdafx . h" ttinclude "netman . h" ttinclude "netmadoc . h" ttifdef JDEBUG ttundef THISJFILE static char BASED_CODE THIS_FILE [ ] = FILE , ttendif
///////////////////////////////////////////////////////////////////////////// // CNetmanDoc
IMPLEMENTJDYNCREATE (CNetmanDoc, CDocument)
BEGINJ1ESSAGEJMAP (CNetmanDoc, CDocument) //{ (AFXJMSGJMAP (CNetmanDoc)
// NOTE - the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see in these blocks of generated code //} }AFX_MSG_MAP ENDJMESSAGEJMAP ( )
II CNetmanDoc construction/destruction
CNetmanDoc : : CNetmanDoc ( )
{
// TODO. add one-time construction code here
CNetmanDoc : . "CNetmanDoc ( )
BOOL CNetmanDoc : : OnNewDocument ( )
{ if ( ! CDocument : : OnNewDocument ( ) ) return FALSE;
// TODO. add reinitialization code here
// (SDI documents will reuse this document) return TRUE;
}
11/1/ l/llll 11 II III llll III III III II II 11 nn in nn nn II I
1 / CNetmanDoc serialization void CNetmanDoc :: Serialize (CArchiveSc ar)
{ if (ar. IsStonng 0 )
(
// TODO : add storing code here
} else
// TODO : add loading code here
///////////////////////////////////////////////////////////////////////////// // CNetmanDoc diagnostics ttifdef JDEBUG void CNetmanDoc : : AssertValid ( ) const
{
CDocument : : AssertValid ( ) ;
} void CNetmanDoc :: Dump (CDumpContextSc dc) const
{
CDocument : : Dump (dc ) ;
} ttendif //JDEBUG
IIIII mm ii 111 miiimiiii i mi ii i 11 mil/mil i //mi ii i III mi
I I CNetmanDoc commands
// netmadoc.h : interface of the CNetmanDoc class // iiiimmimmmmimiimiimmimmimmmmmmimiii/iii class CNetmanDoc : public CDocument
{ protected: // create from serialization only
CNetmanDoc ( ) ;
DECLAREJDYNCREATE (CNetmanDoc)
// Attributes public :
// Operations public :
// Overrides
// ClassWizard generated virtual function overrides
//( (AFXJVIRTUAL (CNetmanDoc) public : virtual BOOL OnNewDocument () ,-
//}}AFXJVIRTUAL
// Implementation public : virtual "CNetmanDoc () ; virtual void Serialize (CArchiveSc ar) ; // overridden for document i/o ttifdef JDEBUG virtual void AssertValid ( ) const; virtual void Dump (CDumpContextSc dc) const; ttendif protected :
// Generated message map functions protected:
//( (AFXJMSG (CNetmanDoc)
// NOTE - the ClassWizard will add and remove member functions h // DO NOT EDIT what you see in these blocks of generated code //} }AFX_MSG DECLARE MESSAGE MAP ( )
}; "
/////////////////////////////////////////////////////////////////////////////
000490 // netman cpo Defines the class behaviors for the application // ttinclude " stdaf h" ttmclude "netman h" tt clude "mamfrm h" ttmclude "netmadoc h" ttmclude "bufdlg h' ttinclude "netmavw h" ttifdef JDEBUG ttundef THIS_FILE static char BASED_CODE THIS_FILE [ ] = FILE , ttendif
///////////////////////////////////////////////////////////////////////////// // CNet anApp
BEGINJMESSAGEJMAP (CNetmanApp, CWinApp)
// { { FXJMSGJMAP (CNetmanApp)
ON_COMMAND ( ID_APP_ABOUT, OnAppAbout)
// NOTE the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see these blocks of generated code
//}}AFXJMSGJMAP
// Standard file based document commands
ON_COMMAND ( ID_FILEJNEW , CWinApp OnFi leNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp OnFileOpen)
// Standard print setup command
ON_COMMAND(IDJFILE_PRINT_SETUP CWinApp OnFilePrmtSetup) END_MESSAGE_MAP ( )
///////////////////////////////////////////////////////////////////////////// // CNetmanApp construction
CNetmanApp CNetmanApp ( )
// TODO add construction code here,
// Place all significant initialization in Initlnstance }
///////////////////////////////////////////////////////////////////////////// // The ore and only CNetmanApp ob3ect
CNetmanApp theApp,
II CNetmanApp initialization
BOOL CNetmanApp Initlnstance ( )
{
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
Enable3dControls 0 ,
LoadStdProfileSettmgs () , // Load standard INI file options (including
// Register the application's document templates. Document templates // serve as the connection between documents, frame windows and views.
CSmgleDocTemplate* pDocTemplate ,- pDocTemplate = new CSmgleDocTemplate (
IDRJMAINFRAME,
RUNTIME_CLASS (CNetmanDoc) ,
RUNTIME_CLASS (CMainFrame) , // main SDI frame window
RUNTIMEj:LASS (CNet anView) ) ; AddDocTemplate (pDocTemplate) ;
// create a new (empty) document OnFileNewO ; if (m lpCmdLinetO] != ' \0 ' )
{
// TODO: add command line processing here
} return TRUE; }
///////////////////////////////////////////////////////////////////////mill
II CAboutDlg dialog used for App About class CAboutDlg : public CDialog public :
CAboutDlg ( ) ,-
// Dialog Data
//( {AFXJDATA (CAboutDlg) enum { IDD = IDD_ABOUTBOX } ; //} }AFXJDATA CFont m_title_font ,-
// Implementation protected: virtual void DoDataExchange (CDataExchange* pDX) ; // DDX/DDV support
//{ (AFXJMSG (CAboutDlg) virtual BOOL OnlnitDialog () ,-
//} }AFX_MSG
DECLAREJMESSAGEJMAP ( )
CAboutDlg: : CAboutDlg () : CDialog (CAboutDlg :: IDD)
//{ (AFXJDATAJINIT (CAboutDlg) //} }AFXJDATAJINIT
void CAboutDlg: : DoDataExchange (CDataExchange* pDX)
CDialog: : DoDataExchange (pDX) ,- // ( (AFXJDATAJMAP (CAboutDlg) // } }AFXJDATAJMAP
BEGIN_MESSAGE_MAP (CAboutDlg, CDialog)
$Q0 9S
// ( (AFXJMSGJMAP ( CAboutDlg) // } } AFX_MSG_MAP END_MESSAGE_MAP ( )
// App command to run the dialog void CNetmanApp : : OnAppAbout ( )
{
CAboutDlg aboutDlg; aboutDlg. DoModal 0 ;
///////////////////////////////////////////////////////////////////////////// // CNetmanApp commands
BOOL CAboutDlg: : OnlnitDialog ()
{
CDialog: : OnlnitDialog ( ) ;
LOGFONT If; memset (Self, 0, sizeof (LOGFONT) ) ,- strcpy (If . IfFaceName, "Monotype Corsiva") ; lf.lfHeight = 24; m_title_font . CreateFontlndirect (Self) ,-
GetDlgltem (IDC_AB0UT1) ->SetFont (S=m_title_font ) ;
return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE
// netman. h : main header file for the NETMAN application // ttifndef AFXWIN_H tterror include 'stdafx.h' before including this file for PCH ttendif ttinclude "resource. h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CNetmanApp:
// See netman. cpp for the implementation of this class
// class CNetmanApp : public CWinApp
{ public :
CNetmanApp () ;
// Overrides
// ClassWizard generated virtual function overrides
//( {AFXJVIRTUAL (CNetmanApp) public : virtual BOOL Initlnstance () ,-
//} }AFXJVIRTUAL
// Implementation
//( (AFXJMSG (CNetmanApp) afx_msg void OnAppAbout ( ) ;
// NOTE - the ClassWizard will add and remove member function // DO NOT EDIT what you see in these blocks of generated coue
//} }AFXJMSG
DECLARE MESSAGE MAP ( )
/////////////////////////////////////////////////////////////////////////////
// netmavw . cpp : implementation of the CNetmanView class // ttinclude " stdafx . h" ttinclude " netman . h" ttinclude "buf dig . h" ttinclude "netmadoc.h" ttinclude "netmavw.h" ttinclude "rtdlg.h"
//+++++++++++++ QLIB +++++++++++++++++++ ttinclude "qlib.h" ttinclude "rt.h" ttinclude "netadmin.h" ttdefine MYTIMER 100
Figure imgf000503_0001
int IDCJLANU = { IDC_GREEN, IDCJYELLOW, IDC_RED} ;
//+++++++++++++ QLIB +++++++++++++++++++
ttifdef JDEBUG ttundef THIS_FILE static char BASEDJCODE THIS_FILE [] = FILE__; ttendif
///////////////////////////////////////////////////////////////////////////// // CNetmanView
IMPLEMENTJDYNCREATE (CNetmanView, CFormView)
BEGINJMESSAGEJMAP (CNetmanView, CFormView) //{ (AFXJMSGJMAP (CNetmanView)
ONJCBN_SELCHANGE ( IDCJNODES , OnSelchangeNodes ) ONJWMJTIMERO
ON_BN_CLICKED (IDC_EXITB, OnExitb) ON_BN_CLICKED(IDC_BUFB, OnBufb) ON_BN_CLICKED ( IDC_ROUTEB , OnRouteb) ON_BN_CLICKED (IDCJFOLCLEARB , OnFolclearb) ON_WMJRBUTTONDOW ( )
ON CBN_SETFOCUS(IDC_NODES, OnSetfocusNodes) //J}AFX_MSGJMAP // Standard printing commands ON COMMANDdD FILE_PRINT, CFormView :: OnFilePrint)
ON_COMMAND(ID_FILE_PRINTJPREVIEW, CFormView. : OnFilePrmtPreview) END_MESSAGE_MAP ( )
I IIIICINIeItIm iainiViiiemw cmonsmtruicitiiiomn/dmesmtrucmtiomniiiummmmmiiiiiiimiiiiiii
CNetmanView . : CNetmanView ( )
: CFormView (CNetmanView: : IDD)
//{ (AFX_DATA_INIT (CNetmanView)
// NOTE the ClassWizard will add member initialization here //} }AFX_DATA_INIT // TODO add construction code here
CNetmanView "CNetmanView ( )
I void CNetmanView -DoDataExchange (CDataExchange* pDX)
{
CFormView.. DoDataExchange (pDX) ,
// { {AFX_DATA_MAP (CNetmanView)
// NOTE the ClassWizard will add DDX and DDV calls here
//} }AFX DATA MAP } II CNetmanView printing
BOOL CNetmanView .OnPreparePrmtmg (CPrmtlnfo* plnfo)
{
// default preparation return DoPreparePrmting (plnfo) ,- } void CNetmanView. : OnBegmPrintmg (CDC* /*pDC*/, CPrmtlnfo* /*pInfo*/)
{
// TODO add extra initialization before printing
} void CNetmanView: : OnEndPrmtmg (CDC* /*pDC*/, CPrmtlnfo* /*pInfo*/)
{
// TODO: add cleanup after printing
} void CNetmanView .OnPnnt (CDC* pDC, CPrmtlnfo*)
{
// TODO. add code to print the controls
)
///////////////////////////////////////////////////////////////////////////// // CNetmanView diagnostics ttifdef JDEBUG void CNetmanView: : AssertValid () const
{
CFormView: :AssertValid () ,
void CNetmanView: : Dum (CDumpContextSc dc) const
{
CFormView: :Dump(dc) ;
}
CNetmanDoc* CNetmanView: : GetDocument ( ) // non-debug version is inline
{
ASSERT (m_pDocument->IsKindOf (RUNTIME_CLASS (CNetmanDoc) ) ) ; return (CNetmanDoc*) m_pDocument ;
} ttendif //JDEBUG
/////////////////////////////////////////////////////////////////// I I CNetmanView message handlers void CNetmanView: : LoadList () // List the possible nodes
{
CComboBox * CB1 = (CComboBox *) this- >GetDlgItem (-IDCJODES) ; CBl->ResetContent () ,- if (smjbase = AttachSharedMemory () ) { IpRT rt = RTROOT; while (rt = NextRT (rt))
CBl- >AddString (RTJJODE (rt ) ) ; // lb- >InsertString ( - 1 , s )
void CNetmanView: : OnlnitialUpdate ( ) {
// Set frame size = Form size GetParentFram ( ) - >RecalcLayout ( ) ResizeParentToFit (FALSE) ; ResizeParentToFit (TRUE) ; m_d = NULL;
/'
*/ LoadList 0 ; if (! smjbase) {
MessageBox ("QNETD not running, please start it . " , 0 , MBJICONSTOP) ;
SetTimer (SHUTDOWNTIME, 10, NULL) ; }
// Show one PIC g_pic = IDCJRED ; g_con = IDC_IS_CON; g_node = SHAREDATA (hostname) ,-
Light (IDCJYELLOW) ;
Con(IDCJNO_CON) ;
CComboBox * CB1 = (CComboBox *) this->GetDlgItern (IDC_N0DES) ; CBl->SelectString(-l,SHAREDATA(hostname) ) ;
SetTimer (MYTIMER, 1000, NULL) ; // 1 second
CFormView: -.OnlnitialUpdate ( ) ; void CNetmanView. : ight (int pic) {
Figure imgf000506_0001
void CNetmanView. : Con (int con) { if (g_con != con) (
GetDlgltem (g_con) ->ShowWmdow (SW_HIDE) GetDlgltem (con) ->ShowW dow (SW_SHOW) ; g_con = con,
t clock_stop, void CNetmanView..OnSelchangeNodes ( )
{
CComboBox * CB= (CComboBox *) thιs->GetDlgItem ( IDCJNODES) g_CBufDlg_state = 10;
CB->GetLBText ( CB->GetCurSel ( ) , g_node .GetBuf fer (100) ) , g_node .ReleaseBuffer ( ) , if (g_node == SHAREDATA (hostname) ) g_remote_node = 0; else g_remote_node = 1,
CString s ,- s . Format ( "%s ' s NETMAN" , LPCTSTR (g_node) ) ,- GetParentFrame ( ) - >SetWιndowText ( s ) ;
SetDlgltemText (IDCJFOLBOX, g_node + "'s fail over list"); // Light (IDC_YELLOW) ; clock_stop = 5; g_smhead. time = g_smhead_old . time = 0,
void CNetmanView: :UpdateStats () { mt 1 ; CString s,
IpSMBUFH b,bb = &eg_smhead_old; // mt local = (g node == SHAREDATA (hostname) ) ,- if (g_remote_node) b = £eg_smhead; else b = smjoase ;
// Is the date moving? if(b->tιme == bb->tιme) clock_stop++; else clock_stop = 0; bb- >tιme = b- >time ;
if (b- >stat . warn ! = bb- >stat . warn)
SetDlgltemlnt ( IDC_WARN, (bb- >stat . warn = b- >stat . warn) ) if (b- >stat . fail ! = bb- >sta . f ail )
SetDlgl temlnt ( IDCJ ARN, (bb- >stat . fail = b- >stat . f ail ) )
if (b->stat .puts != bb- >stat .puts)
SetDlgltemlnt (IDCJPUTS, (bb->stat. puts = b->stat . puts) ) if (b->stat .gets != bb->stat .gets)
SetDlgltemlnt (IDC_GETS, (bb->stat. gets = b- >stat .gets) )
if (b->stat.tx != bb->stat.tx)
SetDlgltemlnt (IDCJ3ENT, (bb->stat.tx = b->stat.tx) ) ; if (b->stat.rx != bb->stat.rx)
SetDlgltemlnt (IDC_RECEIVED, (bb->stat.rx = b->stat.rx) )
if (b->rt_rev != bb->rt_rev)
SetDlgltemlnt (IDCJRTREV, (bb->rt_rev = b->rt_rev) if (b->rt_ver != bb->rt_ver)
SetDlgltemlnt (IDCJTVER, (bb->rt_ver = b->rt ver)
if ((b->rt_rev != bb->rt_rev)) { // RT and FOL update: if ( !b->f iled_servers) { // No Failed servers GetDlglte (IDCJFOL) ->ShowWindow (SW_HIDE) ; // GetDlgltem (IDCJFOLBOX) ->ShowWindow (SWJHIDE) ; GetDlgltem (IDCJFOLCLEARB) ->ShowWindow (SW_HIDE) ; } else {
GetDlgltem (IDCJFOL) - >ShowWindow (SW_SHOW) ; GetDlgltem (IDC_FOLBOX) ->ShowWindow (SW_SHOW) ; GetDlgltem (IDCJFOLCLEARB) ->ShowWindow (SW_SHOW) ;
CListBox* lb = (CListBox*) GetDlgltem ( IDC_FOL) ; lb- >ResetContent ( ) ,- lb->InsertString(-l, "==== FAILOVERS IN USE ===="); for d=0; i<b->failed_servers; i++) { s. Format ("%5d %6s %x %d %d",i+l, b->FO[i] .name,b->FO[i] .ip,b->FO[i] .puts , b->FO [i] .gets) ; lb->InsertString(-l, s) ;
, > '
/* if ( Imemcmp (Scb->stat, Sebb->stat, sizeof (b->stat) ) || moved) ( CListBox* lb = (CListBox*) GetDlgltem (IDC_STATS) ; lb->ResetContent ( ) ; s. Format ( "opens=%d closes=%d openrep=%d" ,b->stat . opens, b->stat . closes, b s .Format ( "puts=%d gets=%d tx=%d rx=%d" , b->stat .puts, b->stat .gets, b->stai_ . ^ s . Format ( "commit=%d abort=%d warn=%d fail=%d" , b->stat . commit , b->stat . abort moved++;
/* if (local) ford = 0, κb->nsbuf , ι++) {
CListBox* lb = (CListBox*) GetDlgltem ( IDC_STATS) , lb- >ResetContent ( ) ; s Format ("%5d %d %s" , ) ; lb->lnsertstrmg ( -1, s) ;
*/
/* if ( (b->hostιp != bb->hostιp) ||
(b->dιag '= bb->dιag) | | moved ) ( s Format ("%s @ %x" , b- >hostname, b->hostιp) ; SetDlgltemText ( IDC Tl,s), s .Format ( "nsbuf=%d dιag=%d tιmeout=%d sec" , b->nsbuf , b- >dιag, (b->tιme_out/l s Format ("faιled=%d rt_rev=%d" , b->faιled_servers , b->rt_rev) , SetDlgltemTex
memcpy (bb, b, sizeof ( *b) ) ;
*/ if (clock_stop > 10 ) Light (IDCJED) , else if (clock_stop > 5 ) Light ( IDC_YELLOW) else Light (IDCJ3REEN) , if (g_remote_node) Con ( IDCJISCON_PIC) , else Con (IDC ISNOTCON PIC),
DWORD Poll (LPVOID ttype)
{ t type = (int) (ttype); if (g_pollmg+ + ) return (1) , if (g node == "" || ( !g_remote_node) ) // Not null or local goto BYE, if (!g_q) { g_q = Qopen ( "QNETD" , PUTJMODE ,0,0,0,0,0) ; if ( !g q) goto BYE, } if (!g_rt || RT_NODE(g_rt) != g_node) if ( i (g_rt = ServerByNode (g_node. GetBuffer (0) )) ) goto BYE; g_q->msgh to_node = RT_IP (g_rt) ; g_q->msgh to_port = RTJPORT (g_rt) ,- strcpy (g_q->msgh. tojlogical, "QNETD") ; strcpy (g_q->msgh.to_server, "QNETD") ;
QsendAndReceive ( g_q , QNETDREQ_MODE , ETMAN_SMBUFH , 0,0,0, (sizeof (SMBUFH) - MAXRTSIZE) , (char *) 6cg_smhead , 0 , 0 ) ,-
BYE. g_pollmg = 0,
return ( 1 ) ;
void CNetmanView: : OnTimer (UINT nIDEvent)
{ if (nIDEvent == MYTIMER) (
DWORD id;
if (g_CBufDlg_state == 20) { g_CBufDlg_state = 0 ,- GetDlglte (IDCJBUFB) ->EnableWindow (TRUE) ;
}
UpdateStats () ; if ( !g_remote node) ,-
CreateThread (NULL, 0, (LPTHREAD_STARTJROUTINE) Poll, (LPVOID) 0,0,Scid)
} else if (nIDEvent == SHUTDOWNTIME) { OnExitb () ; } else (
CFormView: : OnTimer (nIDEvent ) ,-
} } void CNetmanView: : OnExitb 0
{
AfxGetMainWnd ( ) - >DestroyWindo ( ) ;
// CBufDlg d; // d. DoModal () ,- void CNetmanView: :OnBufb()
{
GetDlgltem (IDC_BUFB) ->EnableWindow (FALSE) g_CBufDlg_state = 1; // Starting if (m_d == NULL) m_d = new CBufDlg (this) ,- m d->Create (IDD BUF DLG) ;
void CNetmanView: :OnRouteb ()
{
CRtDlg d; d. DoModal () ,- } void CNetmanView: :OnFolclearb()
( if (g_remote_node) (
QsendAndReceive (g_q, QNETDREQ_MODE , NETMAN_CLR_FOL,
0,0,0, 0,0,0,0);
} else
SHAREDATA (failed_servers) = 0; } void CNetmanView: : OnRButtonDown (UINT nFlags, CPoint point)
GetParentFrame ( ) - >SetMessageText ( " " ) ,- this->Invalidate () ,-
CFormView: :OnRButtonDown (nFlags , point) } void CNetmanView: : OnSetfocusNodes ( )
{
LoadList () ,-
}
// netmavw . h . interface of the CNetmanView class
//
///////////////////////////////////////////////////////////////////////////// class CNetmanView . public CFormView
{ protected: // create from serialization only
CNetmanView () ,
DECLARE_DYNCREATE (CNetmanView) public .
//( (AFXJDATA (CNetmanView) enum{ IDD = IDDJNETMAN_FORM },
// NOTE the ClassWizard will add data members here //} } AFXJDATA // CString m node; mt g_pιc, CBufDlg *m_d, // Attributes public .
CNetmanDoc* GetDocument () ;
// Operations public
// Overrides
// ClassWizard generated virtual function overrides
//( (AFXJVIRTUAL (CNetmanView) public . virtual void OnlnitialUpdate () , protected virtual void DoDataExchange (CDataExchange* pDX) , // DDX/DDV support virtual BOOL OnPreparePrmtmg (CPrmtlnfo* plnfo); virtual void OnBegmPrintmg (CDC* pDC, CPrmtlnfo* plnfo), virtual void OnEndPrmtmg (CDC* pDC, CPrmtlnfo* plnfo); virtual void OnPrmt(CDC* pDC, CPrmtlnfo*);
//} }AFX_VIRTUAL void UpdateStats ( ) ; void LoadList ( ) ; void Light (mt pic); void Con ( int pic); // Implementation public : virtual "CNetmanView () ,- ttifdef JDEBUG virtual void AssertValid ( ) const; virtual void Dump (CDumpContextSc dc) const, ttendif protected
// Generated message map functions protected.
//( (AFXJMSG (CNetmanView) afx_msg void OnSelchangeNodes () , afx_msg void OnTιmer(UINT nIDEvent); afx_msg void OnExitbO; afx_msg void OnBufbO; afx_msg void OnRoutebO; afx_msg void OnFolclearb ( ) ,
afx_msg void OnRButtonDown (UINT nFlags , CPoint point ) ; afx msg void OnSetf ocusNodes ( ) ;
//JJAFXJMSG
DECLARE MESSAGE MAP ( )
}; ttifndef _DEBUG // debug version in netmavw.cpp inline CNetmanDoc* CNetmanView: : GetDocument ( ) ( return (CNetmanDoc* ) m_pDocument ,- } ttendif lllll/ llll lllll
//{ {NOJDEPENDENCIES} }
// Microsoft Developer Studio generated include file.
// Used by netman. re
// ttdefine IDD_ABOUTBOX 100 ttdefine IDD_NETMANJFORM 101 ttdefine IDRJMAINFRAME 128 ttdefine IDRJNETMANTYPE 129 ttdefine IDD_BUF_DLG 130 ttde f ine IDRJQUP 131 ttdefine IDDJ3UFFER 131 ttdefine IDD_RTDLG 132 ttdefine IDR_QDOWN 134 ttdefine IDC_DOWN_PIC 134 ttdefine IDR_DOWN_PIC 134 ttdefine IDR_QNONE 136 ttdef ine IDRJMAN 136 ttdefine IDR_NET 137 ttdefine IDR_NETMAN 138 ttdefine IDRJLANTERN 139 ttdef ine IDRJLANJRED 140 ttdefine IDR_LAN_GRN 141 ttdefine IDR_LAN_YEL 142 ttdefine IDR_NO_CON 143 ttdefine IDR_IS_CON 144 ttdefine IDR_3DIMES 145 ttdef ine IDRJ3DMDS 146 ttdef ine IDCJNODES 1000 ttdefine IDC_ISCON_PIC 1001 ttdefine IDC_IS_CON 1001 ttdef ine IDCJISNOTCONJPIC 1002 ttdefine IDC_NO_CON 1002 ttdefine IDC_GREEN 1003 ttdefine IDC_RED 1004 ttdefine IDC_YELLOW 1005 ttdefine IDC_EXITB 1009 ttdefine IDCJROUTEB 1010 ttdefine IDC_BUFB 1011 ttdefine IDC_TRANB 1012 ttdefine IDC_FOLCLEARB 1013 ttdefine IDC_GETS 1016 ttdefine IDC_PUTS 1017 ttdefine IDC_SENT 1018 ttdefine IDC_RECEIVED 1019 ttdefine IDC_FAIL 1020 ttdefine IDC_WARN 1021 ttdefine IDCJRTREV 1022 ttdefine IDC_RTVER 1023 ttdefine IDC_FOL 1024 ttdefine IDCJBUFLB 1025 ttdefine IDC_BUFER_LB 1025 ttdefine IDCJRTREE 1026 ttdefine IDC_GETB 1027 ttdefine IDC_COPYB 1027 ttdefine IDC_BROADCASTB 1028 ttdefine IDC_FOLBOX 1028 ttdefine IDCJTREELB 1029 ttdefine IDC_PB1 1030 ttdefine IDC_CONLB 1030 ttdefine IDC PB2 1031
ttdefine IDC_PB3 1032 ttdef ine IDC_PB4 1033 ttdef ine IDCJPB5 1034 ttdefine IDC_PB6 1035 ttdef ine IDCJPB7 1036 ttdefine IDCJPB8 1037 ttdefine IDCJDATE 1038 ttdefine IDC_MID 1039 ttdef ine IDC_TO 1040 ttdef ine IDCJFROM 1041 ttdef ine IDCJPBO 1042 ttdefine IDCJDATEL 1043 ttdef ine IDCJMIDL 1044 ttdef ine IDCJTOL 1045 ttdef ine IDCJFROML 1046 ttdef ine IDC_T02 1047 ttdef ine IDC_RTJTITLE 1048 ttdef ine IDCJLOGO 1049 ttdefine IDC_ABOUTl 1050
// Next default values for new obj ects
// ttifdef APSTUDIO_INVOKED ttifndef APSTUDIO_READONLY_SYMBOLS ttdefine _APS_3D_CONTROLS 1 ttdefine _APS_NEXT_RESOURCE_VALUE 134 ttdefine _APS_NEXT_COMMANDJfALUE 32771 ttdefine _APS_NEXT_CONTROL_VALUE 1051 ttdefine _APS_NEXT_SYMED_VALUE 101 ttendif ttendif
// rtdlg . cpp : implementation file // ttinclude " stdafx . h" ttinclude "netman . h" ttinclude " rtdlg . h"
//+++++++++++++ QLIB +++++++++++++++++++ ttdefine QJLIB ttinclude " qlib . h" ttinclude "rt . h" ttinclude " netadmin . h" ttinclude "qnetd . h" ttdefine RTTIMER 104 extern IpSMBUFH smjoase,- extern SMBUFH g smhead; extern SMBUFH g smhead old; extern CString g node,- extern int g_polling,- extern int g remote node ,- extern int g_pic; extern lpQHANDLE g_q; extern IpRT g rt;
/ /+++++++++++++ QLIB +++++++++++++++++++
ttifdef JDEBUG ttundef THIS_FILE static char BASED_CODE THISJFILE [ ] = __FILE ; ttendif
///////////////////////////////////////////////////////////////////////////// // CRtDlg dialog
CRtDlg: : CRtDlg (CWnd* pParent /*=NULL*/) : CDialog (CRtDlg :: IDD, pParent)
//{ (AFX_DATA_INIT (CRtDlg)
// NOTE: the ClassWizard will add member initialization here //} }AFXJDATAJINIT
void CRtDlg: : DoDataExchange (CDataExchange* pDX)
{
CDialog: : DoDataExchange (pDX) ; // { (AFXJDATAJMAP (CRtDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here //}}AFXJDATAJMAP
BEGIN_MESSAGE_MAP (CRtDlg, CDialog) // { (AFX_MSG_MAP (CRtDlg) ON BN CLICKED (IDCJCOPYB, OnCopyb)
, OnBroadcastb)
Figure imgf000516_0001
///////////////////////////////////////////////////////////////////////////// // CRtDlg message handlers
/*
typedef struct JTVJITEM ( tvi
UINT mask;
HTREEITEM hitern; // item this structure refers to
UINT state ;
UINT stateMask;
LPSTR pszText; int cchTextMax; int ilmage; int iSelectedlmage; int cChildren;
LPARAM IParam; // 32-bit value to associate with item
TV ITEM;
'I
BOOL CRtDlg: : OnlnitDialog ( )
{
CDialog: : OnlnitDialog ( ) ;
CString s ; // int i;
/'
TV_INSERTSTRUCT TreeCtrlltem;
TreeCtrlltem.hParent = TVI_ROOT;
TreeCtrlltem. hlnsertAfter = TVIJLAST;
TreeCtrlltem. item. mask = TVIFJTEXT | TVIF_PARAM;
TreeCtrlltem. item. pszText = "Fire";
TreeCtrlltem. item. IParam = 0 ,-
HTREEITEM hTreelteml = m_Property . Insertltem (ϋTreeCtrllte )
TreeCtrlltem.hParent = hTreelteml; TreeCtrlltem. item. pszText = "Decay"; TreeCtrlltem. item. IParam = 1; mJProperty. Insertltem (ϋTreeCtrlltem) ;
TreeCtrlltem. item. pszText = "Flammability" ; TreeCtrlltem. item. IParam = 2; mJProperty. Insertltem (ScTreeCtrlltem) ;
TreeCtrlltem. item. pszText = "Maximum Heat"; TreeCtrlltem. item. IParam = 3; mJProperty. Insertltem TreeCtrlltem) ;
TreeCtrlltem.hParent = TVI_ROOT;
TreeCtrlltem. item. pszText = "Render";
TreeCtrlltem. item. IParam = 0 ;
HTREEITEM hTreeItem2 = m_Property. Insertltem (ScTreeCtrlltem)
TreeCtrlltem.hParent = hTreeItem2; TreeCtrlltem. item. pszText = "Smoothness" TreeCtrlltem. item. IParam = 6 ; m_Property . Insertltem (ScTreeCtrl Item) ; m_Property . Expand (hTreelteml , TVEJEXPAND) m_Property. Expand (hTreeItem2 , TVE_EXPAND)
TV_ITEM tvi, TV_INSERTSTRUCT tvins ; tvms . hParent = TVI_ROOT ; tvms . hlnsertAfter = TVI_LAST; // TVIJFIRST tvms . item = tvi ; tvi . mask = TVIF_TEXT | TVIFJPARAM; tvi . hi tern = NULL ; tvi . state = NULL ; tvi . stateMask = NULL ; tvi . pszText = "TEXZT" , tvi . cchTextMax = 6 , tvi. lImage = NULL, tvi . lSelectedlmage = NULL, tvi.cChildren = NULL, tvi.mask = NULL; tvi. IParam = NULL;
HTREEITEM til, tl = NULL, CTreeCtrl * CT,
CT = (CTreeCtrl *) thιs->GetDlgItem (IDCJRTJTREE) ; til = CT->InsertItem(&tvms) ,- tvi. pszText = "TEXZT"; tvi . IParam = 1; ti = CT->InsertItem(&tvιns) ; tvi. pszText = "TEXZT"; tvi . IParam = 2 ; ti = CT->InsertItem(&tvxns) ,- CT->Expand(tιl,TVE_EXPAND) ,-
*/
// GetDlgltem (IDCJCOPYB) - >ShowWmdow (SW_SHOW) ; s .Format ("%s ' s Routing Table (rev %d/%d) " ,g_node, g_smhead.rt_ver,g_smhead.rt_ SetDlgltemText (IDC_RT_TITLE, s) ; if (g_remote_node) (
GetDlgltem (IDCJCOPYB) ->EnableWmdow (TRUE) ,- GetDlgltem (IDCJBROADCASTB) ->EnableWmdow (FALSE) ; } else {
GetDlgltem (IDC_COPYB) ->EnableWmdow (FALSE) ; GetDlgltem (IDC_BROADCASTB) ->EnableWιndow (TRUE) ;
}
CListBox* lb = (CListBox*) GetDlgltem ( IDCJTREELB) ; lb->ResetContent 0 ,-
CString indent,
SMBUF b,
IpRT rt = RTROOT,
// Get the RT Data if (g_remote_node) ( memset ( Scb mdata, 0, (sizeof (b. mdata) ) ) ,-
QsendAndRecelve (g_q, QNETDREQJMODE , NETMAN_RT_READ , 0,0,0,
(sizeof (b mdata) ), (char*) Scb . mdata, 0 , 0) , rt = (RT*) Scb mdata, } else rt = RTROOT,
// Load the box while (rt = NextRT (rt)) ( s. Format ("%-12s %s" ,RT_NODE(rt) , RTJJTYPE ( rt ) ) ; lb->InsertStnng (-1, s) , char t, *e, *s = RT_APPS(rt); while (strlen(s) > 2 ) (
If (*s == 1 [') indent S++ ,
} else if (*s = indent S++ ,
} else if (*s = . ' ) { indent S++ ,
} else { if (e = strpbrk(s, ",]")) ( t = *e, *e = NULL, lb->InsertStrmg ( -1, indent + s),
*e = t, s = e , } else { break, // should never happen
/*
// Load the sockets box lb = (CListBox*) GetDlgltem ( IDCJCONLB) ; lb->ResetContent 0 ; if (g_remote_node) ( memset (&b. mdata, 0, (sizeof (b. mdata) ) ) ,
QsendAndReceive (g_q, QNETDREQJMODE, NETMAN_SOCKETS , 0,0,0,
(sizeof (b. mdata) ) , (char*) Scb .mdata, 0,0), IpSSA sa = (SSA*) Scb . mdata, for (l = 0,ι < sa->sockets, ι++) { s.Format("%x %d" , sa->ss [l] . ip, sa->ss [l] .port) lb->InsertStπng(-l, indent) , }
} else ( // local
IpST stp = STroot,
while (stp) { s. Format ("%x %d",stp->ip, stp->port); lb->InsertString(-l, indent) ,-
*/ return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
void CRtDlg: :OnCopyb()
{
GetDlgltem (IDC_COPYB) - >EnableWindow (FALSE) ; if (g_q) if (CopyRT (g_q->msgh. to_node) )
GetDlgltem ( IDCJBROADCASTB) - >EnableWindow (TRUE) GetDlgltem ( IDCJCOPYB) - >EnableWindow (TRUE) ;
void CRtDlg: : OnBroadcastb ()
{
GetDlgltem (IDCJBROADCASTB) ->EnableWindow (FALSE) BroadcastRT () ,-
GetDlgltem (IDCJBROADCASTB) ->EnableWindow (TRUE) ;
void CRtDlg: : OnRButtonDown (UINT nFlags, CPoint point)
{
GetParentFrame ( ) - >SetMessageText ( " " ) ; this->Invalidate () ;
CDialog: : OnRButtonDown (nFlags , point) ,-
// rtdlg.h : header file //
///////////////////////////////////////////////////////////////////////////// // CRtDlg dialog class CRtDlg : public CDialog
{
// Construction public :
CRtDlg (CWnd* pParent = NULL); // standard constructor
// Dialog Data
// { (AFXJDATA (CRtDlg) enum { IDD = IDDJRTDLG } ;
// NOTE: the ClassWizard will add data members here //} } AFXJDATA
// Overrides
// ClassWizard generated virtual function overrides
//( (AFXJVIRTUAL (CRtDlg) protected : virtual void DoDataExchange (CDataExchange* pDX) ; // DDX/DDV support
//} } AFXJIRTUAL
// Implementation protected:
// Generated message map functions
, CPoint point);
Figure imgf000520_0001
// stdafx.cpp : source file that includes just the standard includes
// netman. pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information ttinclude "stdafx.h"
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
// ttinclude <afxwin.h> // MFC core and standard components ttinclude <afxext.h> // MFC extensions ttinclude <afxcmn.h> // MFC TREE
// dbdlg.cpp : implementation f le // ttinclude "stdafx.h"
//ttmclude "oentrvw. h"
ttinclude "oentry. h" ttmclude "dbdlg.h" ttmclude "Odlg.h"
// ttdefine ORACLE causes oraread () orawrite () to be exteraly defined ttifndef ORACLE ttdefine ORACLE ttendif ttmclude "oraomq. h"
ttifdef JDEBUG ttundef THISJFILE static char BASED_CODE THIS_FILE[] = FILE , ttendif ttdefine DBJTIMER 200 ttdefme INITJTIMER 10 ttdefine RESTOCK_QTY 100000 mt g_orders_mode = 0; // Display orders or items extern CString g_ιtem[] , extern CStrmg g_cust [] , extern mt g_prιce[6] , extern t g_qty[6] , mt g_qty_old [6] , extern int g_purchases [6] , mt g_purchases_old [6] ,- extern mt g_num_purchases [6] ; int g_num_purchases_old [6] , extern int g_total_sales, int g_total_sales_old; extern mt g_db_run; extern mt g_ora_state; mt g_ora_state_old = -1; extern CFont g_tιtle_f ont , extern CFont g_text_font, enum dblDC (qtyJIDC, price JIDC, ltemJIDC} , mt ALLJTEXTJDB [] = { IDC_ORDERS_ITEMS, IDC_DB_REFILL, IDC_DB_B0X, IDOK ,
IDCJTll , IDCJT12 , IDCJT13 , IDCJT21 , IDCJT22 , IDCJT23 ,
IDC_DB_Q0 , IDC_DB_Q1 , IDC_DB_Q2 , IDC_DB_Q3 , IDC_DB JQ4 , IDC_DB_Q5 IDC_DB_P0 , IDC_DB_P1 , IDCJDB_P2 , IDC_DB_P3 , IDC_DB_P4 , IDCJDBJP5 IDC_DB_I0, IDC_DB_I1, IDC_DB_I2, IDC_DB_I3, IDCJDB 14, IDC_DB mt g_IDCt [2] [3] =( IDC_T11 , IDC_T12 , IDCJT13 | ,
IDCJT21 , IDC_T2 , IDC_T23 } } ; t g_IDCs [3] [6] = { IDC_DB_Q0 , IDC_DB_Q1 , IDC_DB_Q2 , IDC_DB_Q3 , IDC_DB_Q4 , IDC_DB_Q
f IDC_DB_P0 , IDC_DB_P1 , IDC_DB_P2 , IDC_DB_P3 , IDC JDB_P4 , IDC_DB_P5 [IDCJDB_I0, IDC_DB_I1,IDC_DB 12, IDC_DB_I3, I DC_DB JI 4 , IDC_DB_I5
CString g_item_tites [] = ( "Qty" , "Price" ," Item"]";
CString g_order_titles [] = {"#", "Amt ", "Customer" } ;
/ 1111111 n mini i mi 11 II
1/ CDbDlg dialog 11 iimiimm mi i m 1111 / / //' 111
CDbDlg: : CDbDlg (CWnd* pParent /*=NULL*/) : CDialog (CDbDlg :: IDD, pParent)
//{ (AFXJDATA_INIT(CDbDlg)
// NOTE: the ClassWizard will add member initialization here //} }AFX DATA INIT
void CDbDlg: : DoDataExchange (CDataExchange* pDX)
{
CDialog: : DoDataExchange (pDX) ,- //( (AFXJDATAJMAP (CDbDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here //} }AFX_DATA_MAP
BEGINJMESSAGEJMAP (CDbDlg, CDialog)
// { (AFXJMSGJMAP (CDbDlg)
ON_BN_CLICKED ( IDCJDRDERS_ITEMS , OnOrders11ems)
ON_WM_TIMER ( )
ON_WM_CREATE ( )
ONJWM_DESTROY ( )
ON_BN_CLICKED ( IDC_DB_REFILL, OnDbRefill)
ON WM_RBUTTONDOWN ( )
//J}AFXJMSGJMAP ENDJMESSAGEJMAP ( )
///////////////////////////////////////////////////////////////////////////// // CDbDlg message handlers void CDbDlg: : OnOrdersItems 0 int i , j ; CString s; if (g_orders_mode) ( // Go into Items mode g_orders_mode = 0 ,-
SetDlgltemText (IDC_DB_REFILL, "Refill") ;
// Set DB titles
SetDlgltemText (IDCJDBJBOX, "Database Items") ; SetDlgltemText (IDC_ORDERS_ITEMS, "Orders") ; for (i=0,-i<2;i++) for (j=0; j<3; j++)
SetDlgltemText (gJIDCt [i] [j] , g_item_tites [j] ) ,- // Set DB values for (i=0; i<6 ;i++) { // For each item
SetDlgltemlnt (g_IDCs [qty_IDC] [i] ,g_qty[i]) ; s. Format ("$%d.00" ,g_price [i] ) ;
SetDlgltemText (g_IDCs [price_IDC] [i] , s) ;
SetDlgltemText (gJIDCs [iterrjIDC] [i] , g_item[i]) ;
} else { // Go into Orders mode g_orders_mode = 1 ; SetDlgltemText (IDC_DB_REFILL, "Clear") ;
// Set DB titles
SetDlgltemText (IDCJDB_BOX, "Database Orders") ; SetDlgltemText (IDCJDRDERSJITEMS, "Items") ; for (i=0 ; i<2 ; i++) for ( j=0; j<3; j++)
SetDlgltemText (g_IDCt [i] [j] , g_order_titles [j] ) ; // Set DB values for (i=0; i<6 ;i++)( // For each item
SetDlgltemlnt (gJIDCs [qtyJIDC] [i] , g_num_purchases [i] ) ; SetDlgltemlnt (g_IDCs [price_IDC] [i] ,g_purchases [i] ) ; SetDlgltemText (gJIDCs [item_IDC] [i] , g_cust [i] ) ,-
} for (i=0; i<6 ;i++){ // Invalidate any histoy g_num_purchases_old [i] = g_purchases_old [i] = g_qty_old[i] = -1;
void CDbDlg: : OnTimer (UINT nIDEvent)
{ int i , re, price, stock, cust_orders, cust_sales ; CString s,- if (nIDEvent == DBJTIMER) ( if (g_db_run < 20) { if (g_db_run == 0) this- >DestroyWindow ( ) ; if (g_db_run == 1) (g_orders_mode = 1; OnOrdersItems () ; g_db_run = 20,-} if (g_ora_state) ( // oracle db if (g_orders_mode) ( for (i=0; i<6 ;i++){ // For each item if ( (re = oracustr (g_cust [i] .GetBuffer (0) , &cust__orders , &cust_ s .Format ( "OraCustRead ErroR %d",rc); GetParentFrame () ->SetMessageText (s) ; if (g__num_purchases_old[i] != cust_orders)
SetDlgltemlnt (g_IDCs [qty_IDC] [i] , (g_num_purchases_old [i] = c if (g_purchases_old [i] != cust_sales)
SetDlgltemlnt (g_IDCs [price_IDC] [i] , (g_purchases_old [i] = cust
} else ( for (i=0; i<6 ;i++){ // For each item if ( (re = oraread (g_item[i] .GetBuffer (0) , &price, &stock) ) ) (
s . Forma ( "OraRead ErroR %d",rc); GetParentFrame ( ) ->SetMessageText (s) ;
} if (g_qty_old [i] != stock)
SetDlgltemlnt (gJIDCs [qty IDC] [i] , (g qty old[i] = stock)); }
} else if (g_orders_mode) ( // NOT ora_state, so use the local db for (ι = 0; ι<6 ,-i++){ // For each item if (g_num_purchases_old [i] != g_num_purchases [i] )
SetDlgltemlnt (g_IDCs [qty_IDC] [i] , (g_num_purchases_old [i] = g nu if (g_purchases_old [i] != g_purchases [i] ) _
SetDlgltemlnt (g_IDCs [price_IDC] [i] , (g_purchases_old [i] = g_purcha
} else { // local db for (i=0; i<6 ;i++){ // For each item if (g_qty[ij !- g_qty_old [i] ) SetDlgltemlnt (gJIDCs [qty__IDC] [i] , (g_qty old [i] = g qty[i]));
> > " - - - if (g_total_sales_old != g_total_sales)
SetDlgltemlnt (IDC_DB_SALES, (g_total_sales_old = g_total_sales) ) ;
if (g_ora_state_old != g_ora_state) { if (g_ora_state_old = g_ora_state)
SetDlgltemText (IDCJBIGJTITLE, "Oracle") ; else
SetDlgltemText (IDCJBIGJTITLE, "Local DB") ;
} else if (nIDEvent == INITJTIMER) ( KillTimer (INITJTIMER) ;
GetDlgItem(IDC_BIG_TITLE) ->SetFont (&g_title_font ) if (g_ora_state)
SetDlgltemText (IDC_BIG_TITLE, "Oracle") ; else
SetDlgltemText (IDC_BIG_TITLE, "Local DB") ;
} else
CDialog: : OnTimer (nIDEvent) ;
mt CDbDlg: : OnCreate (LPCREATESTRUCT IpCreateStruct) if (CDialog: :OnCreate (IpCreateStruct) == -1) return -1;
SetTimer (DBJTIMER, 200, NULL) ; SetTimer (INITJTIMER, 200, ULL) g_db_run = 1; // Start return 0 ,- } void CDbDlg: :OnDestroy()
0005ro,
g_db_run = 40;
CDialog :OnDestroy ( ) ,
KillTimer (DB TIMER); } void CDbDlg -OnOKO
{ g_db_run = 40, // Re enable the show db call button thιs->DestroyWιndow() ,
// CDialog. : OnOKO , } void CDbDlσ OnDbRefilK)
{ mt ι,rc, CString s, if (g_ora_state) { for (ι=0,ι<6,ι++) ( if (g_orders_mode) ( if ( (re = oracustw (g_cust [1] GetBuffer (0) , 0, 0)) ) ( s Format ( "OraCustWπte ERRor %d",rc), GetParentFrame () - >SetMessageText (s) ,
} else ( // in items mode if (re = orawrite (g_ιtem[ι] GetBuffer (0) , RESTOCK_QTY) ) ( s Format ( "OraWπte ERRor %d",rc), GetParentFrame () - >SetMessageText (s) ,
Figure imgf000527_0001
void CDbDlg. OnRButtonDown (UINT nFlags, CPoint point)
{
GetParentFrame ( ) - >SetMessageText ( " " ) , this- invalidate () ,
CDialog. : OnRButtonDown (nFlags, point) ;
BOOL CDbDlg: .OnlnitDialog 0
CDialog: : OnlnitDialog ( ) ;
// Fonts int i = 0; while (ALL TEXTJDB [i] )
GetDlgltem (ALLJTEXTJDB [i++] ) ->SetFont (&g_text_font ) ; return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE
// dbdlg.h : header file //
///////////////////////////////////////////////////////////////////////////// // CDbDlg dialog class CDbDlg : public CDialog
{
// Construction public :
CDbDlg (CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{ (AFXJDATA (CDbDlg) enum ( IDD = IDDJDBDLG } ;
// NOTE: the ClassWizard will add data members here //}} AFXJDATA
// Overrides
// ClassWizard generated virtual function overrides
// { (AFXJVIRTUAL (CDbDlg) protected : virtual void DoDataExchange (CDataExchange* pDX) ; // DDX/DDV support
//} } AFXJVIRTUAL
CFont m_title_font ; int m_was_inited;
// Implementation protected :
// Generated message map functions // ( {AF JMSG (CDbDlg) afx_msg void OnOrdersItems () ; afx_msg void OnTimer (UINT nIDEvent); afx_msg int OnCreate (LPCREATESTRUCT IpCreateStruct); afx_msg void OnDestroyO; virtual void OnOKO; afx_msg void OnDbRefill ( ) ,- afx_msg void OnRButtonDown (UINT nFlags, CPoint point); virtual BOOL OnlnitDialog () ; //} }AFX_MSG DECLARE MESSAGE MAP ( ) }; - - // mainfr . cpp : implementation of the CMainFrame class // ttinclude " stdafx . h" ttinclude "oentry . h" //ttinclude "OpDlg . h" ttinclude "mainfrm . h" ttifdef JDEBUG ttundef THIS_FILE static char BASED_CODE THISJFILE [] = FILE ; ttendif
///////////////////////////////////////////////////////////////////////////// // CMainFrame
IMPLEMENTJDYNCREATE (CMainFrame , CFrameWnd)
BEGINJMESSAGEJMAP (CMainFrame , CFrameWnd) //{ (AFX_MSG_MAP (CMainFrame)
// NOTE - the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see in these blocks of generated code ON WM_CREATE ( ) //J}AFXJMSGJMAP END_MESSAGE_MAP ( )
///////////////////////////////////////////////////////////////////////////// // arrays of IDs used to initialize control bars
// toolbar buttons - IDs are command buttons static UINT BASED CODE buttons [] =
{
// same order as in the bitmap 'toolbar.bmp'
ID_FILE_NEW,
ID_FILE_OPEN,
ID_FILE_SAVE,
IDJSEPARATOR,
ID_EDIT_CUT,
IDJEDITJTOPY,
ID_EDIT_PASTE,
IDJSEPARATOR,
ID_FILE_PRINT,
ID APP ABOUT, }; " " static UINT BASED CODE indicators [] =
{
IDJSEPARATOR, // status line indicator
ID_INDICATOR_CAPS , ID_I DICATORJNUM, ID INDICATOR SCRL,
}; /////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction
CMainFrame : : CMainFrame ( )
{
// TODO: add member initialization code here
CMainFrame ~CMainFrame ( )
! mt CMainFrame: : OnCreate (LPCREATESTRUCT IpCreateStruct)
{ if (CFrameWnd- : OnCreate (IpCreateStruct) == -1) return -1, if ( i m_wndToolBar Create(thιs) ||
1 m_wndToolBar . LoadBitmap ( IDRJMAINFRAME) 1 m_wndToolBar . SetButtons (buttons , sizeof (buttons) /sizeof (UINT) ) )
(
TRACEO ("Failed to create toolbar\n"), return -1, // fail to create
/* Derek's remove tool bar */ wndToolBar ShowW dow (SW_HIDE) ,
if ( !m_wndStatusBar. Create (this) ||
!m_wndStatusBar . Setlndicators (indicators, sizeof (indicators) /sizeof (UINT) ) )
{
TRACEO ( "Failed to create status bar\n"), return -1, // fail to create }
// TODO. Delete these three lines if you don't want the toolbar to // be dockable m_wndToolBar.EnableDockmg(CBRS_ALIGN_ANY) ; EnableDockmg(CBRS_ALIGN_ANY) , DockControlBar (&m_wndToolBar) ,
// TODO. Remove this if you don't want tool tips m_wndToolBar . SetBarStyle (m_wndToolBar . GetBarStyle ( ) | CBRSJTOOLTIPS | CBRS_FLYBY) , return 0,
}
///////////////////////////////////////////////////////////////////////////// // CMainFrame diagnostics ttifdef JDEBUG void CMainFrame: .AssertValid () const
{
CFrameWnd. : AssertValid ( ) ,
} void CMainFrame..Dump (CDumpContextSc dc) const
{
CFrameWnd. :Dump(dc) ,
ttendif //JDEBUG
///////////////////////////////////////////////////////////////////////////// // CMainFrame message handlers
// mainfrm.h : interface of the CMainFrame class
//
///////////////////////////////////////////////////////////////////////////// class CMainFrame : public CFrameWnd
{ protected: // create from serialization only
CMainFrame () ,-
DECLAREJDYNCREATE (CMainFrame)
// Attributes public :
// Operations public :
// Overrides
// ClassWizard generated virtual function overrides //{ (AFXJVIRTUAL (CMainFrame) //} }AFXJVIRTUAL
// Implementation public : virtual ~CMainFrame ( ) ,- ttifdef JDEBUG virtual void AssertValid 0 const; virtual void Dump (CDumpContextSc dc) const; ttendif protected: // control bar embedded members CStatusBar m_wndStatusBar ; CToolBar m_wndToolBar ;
// Generated message map functions protected:
// { (AFXJMSG (CMainFrame) afx_msg int OnCreate (LPCREATESTRUCT IpCreateStruct);
// NOTE - the ClassWizard will add and remove member functions h // DO NOT EDIT what you see in these blocks of generated code //} }AFXJMSG DECLARE MESSAGE MAP ( )
};
/////////////////////////////////////////////////////////////////////////////
// Odlg . cpp : implementation file // ttinclude " stdafx . h" ttinclude "oentry . h" ttinclude "Odlg . h"
// ttdefine ORACLE causes oraread ( ) orawrite to be exteraly defined ttifndef ORACLE ttdef ine ORACLE ttendif ttinclude "oraomq . h"
ttifdef JDEBUG ttdef ine new DEBUGJ EW ttundef THISJFILE static char THIS_FILE [ ] = FILE ; ttendif extern int g_options_run; extern int g_fill_delay; extern int g_place_delay; extern int g_place_tpm; extern int g_poll_pps; extern int g_poll_delay; extern int g_clear_stats ; extern int g_ora_state; extern COLORREF g_new_color; extern char g_oracle_con_str [80] ; extern CFont g_text_font ; int ALLJTEXTJDH = { IDOK, IDC_COLOR, IDC_CLRSTATS, IDCJORACREATE,
IDCJFILLBOX, IDC_DLY_EB, IDCJDLYMAX, IDC_DLYMIN, IDCJDLYJLAB, IDC_POLL_BOX, IDC_POLL_EB, IDC_POLLMAX, IDC_POLLMIN, IDC_POLL_L IDC_AUTOBOX, IDC_AUTOJEB, IDC_AUTOMAX, IDC_AUTOMIN, IDC AUTO LA
/////////////////////////////////////////////////////////////////////////////
// COdlg dialog
COdlg: : COdlg (CWnd* pParent /*=NULL*/) : CDialog (COdlg :: IDD, pParent)
{
//{ (AFXJDATA_INIT (COdlg)
// NOTE: the ClassWizard will add member initialization here
//} }AFX DATA INIT
void COdlg: : DoDataExchange (CDataExchange* pDX)
CDialog: -. DoDataExchange (pDX) ,- // { (AFXJDATAJMAP (COdlg)
// NOTE: the ClassWizard will add DDX and DDV calls here //}}AFXJDATAJMAP
0005 Γ:3QO BEGINJMESSAGE JMAP (COdlg , CDialog)
/ / { ( AFXJMSGJMAP ( COd 1 g )
ON_WM_CREATE ( )
ONJENJJPDATE ( IDC_AUTO_EB , OnUpdateAutoEb)
ON_WM_VSCROLL ( )
ON_EN_UPDATE (IDC_POLL_EB , OnUpdatePollEb)
ON_EN_UPDATE ( IDC_DLY_EB , OnUpdateDlyEb)
ON_BN_CLICKED (IDCJOOLOR, OnColor)
ON_BN_CLICKED(IDC_CLRSTATS, OnClrstats)
ON BN_CLICKED(IDC_ORACREATE, OnOracreate)
//J}AFXJMSGJMAP ENDJMESSAGEJMAP ( )
///////////////////////////////////////////////////////////////////////////// // COdlg message handlers int COdlg: : OnCreate (LPCREATESTRUCT IpCreateStruct)
{ if (CDialog: :OnCreate (IpCreateStruct) == -1) return -1; g_options_run = 1; // start return 0; } void COdlg: : OnOK
{ g_options_run = 40; // Re-enable the options call button this->ShowWindow(SW_HIDE) ;
// this->DestroyWindow () ; // CDialog: :OnOKO ; }
/* void COdlg: :OnDestroy 0 g_options_run = 40; // Re-enable the options call button // CDialog: :OnDestroy() ;
}
* /
void COdlg: :OnVScroll (UINT nSBCode, UINT nPos , CScrollBar* pScrollBar)
/* if ( (nSBCode == SB_PAGEUP ) | | (nSBCode == SB_PAGEDOWN) ) ( if (pScrollBar- >GetDlgCtrlID ( ) == IDCJDLY_SLD) pScrollBar- >SetScrollPos (MAXJDLY + MINJDLY - g_f ill_delay, TRUE) ;
*/ if (nSBCode == SBJENDSCROLL) (
} else if (pScrollBar- >GetDlgCtrlID ( ) == IDC_DLY_SLD) ( if (((int)nPos != g_fill_delay) ScSc (MIN_DLY <= nPos) ScSc (nPos <= Mm_ SetDlgltemlnt (IDC DLY EB,g fill delay = MAX DLY + MIN DLY - nPos) ; ~~
} "
} else if (pScrollBar- >GetDlgCtrlID ( ) == IDC_AUTO_SLD) { if (((int)nPos != g_place_delay) ScSc (MIN_AUTO <= nPos) ScSc (nPos <= MA SetDlgltemlnt (IDC_AUTO_EB, (g_place_tpm = MAX_AUTO + MINJAUTO - nPos)); g place delay = 60000/g place tpm;
} " } else if (pScrollBar- >GetDlgCtrlID () == IDCJPOLL_SLD) { if (((int)nPos != g_poll_pps) ScSc (MIN_POLL <= nPos) ScSc (nPos <= MAX_P SetDlgltemlnt (IDC_POLL_EB, (g_poll_pps = MAX_POLL + MIN_POLL - nPos) ) ; ~ g poll_delay = 1000/g_poll_pps ;
CDialog: : OnVScroll (nSBCode, nPps, pScrollBar); }
BOOL COdlg: : OnlnitDialog ()
{
CDialog: : OnlnitDialog ( ) ;
// GetParentFrame 0 ->SetWindowText (m_inst + " Options"); this->SetWindowText (m_inst + " Options");
SetDlgltemlnt (IDC DLYMAX, MAXJDLY) ; SetDlgltemlnt (IDC_DLYMIN, MINJDLY) ;
SetDlgltemlnt (IDC_AUTOMAX,MAX_AUTO) ,-
SetDlgltemlnt (IDCJAUTOMIN, MIN_AUTO) ;
SetDlgltemlnt (IDCJPOLLMAX, MAXJPOLL) ;
SetDlgltemlnt (IDC_POLLMIN,MIN_POLL) ;
SetDlgltemlnt ( IDC_DLY_EB, g_fill_delay) ,- SetDlgltemlnt ( IDC_POLL_EB, g_poll_pps) ; SetDlgltemlnt ( IDC_AUTO_EB, g_place_tpm) ;
// (CSliderCtrl *) xxx = GetDlgltem (IDCJDLYJSLD) ; HWND hTrack = GetDlgltem ( IDCJDLY_SLD) - >mJnWnd; : :SendMessage (hTrack, TBMJSETRANGEMIN, TRUE, MIN_DLY) ;// MINDLY : :SendMessage (hTrack, TBM_SETRANGEMAX, TRUE, MAXJDLY) ;// MAXDLY
: -.SendMessage (hTrack, TBMJSETTICFREQ, 100, TRUE) ,- // 10 ticks (MAXDLY - MINDLY :: SendMessage (hTrack, TBMJSETPOS, TRUE, MINJDLY + MAXJDLY - g_fill_delay) ; // 1 hTrack = GetDlglte (IDC_AUTOJSLD) ->m_hWnd;
: SendMessage (hTrack, TBM_SETRANGEMIN, TRUE, MIN_AUTO) ;// MINDLY
: SendMessage (hTrack, TBMJSETRANGEMAX, TRUE, MAXJAUTO) ; // MAXDLY
:SendMessage (hTrack, TBM_SETTICFREQ, 500, TRUE) ; // 10 ticks (MAXDLY - MINDLY
: SendMessage (hTrack, TBMJSETPOS, TRUE, MAX_AUTO + MIN_AUTO - g_place_tpm) ; // hTrack = GetDlgltem (IDCJPOLLJ3LD) - >m_hWnd; SendMessage(hTrack, TBMJSETRANGEMIN, TRUE, MIN_POLL) ;// MINDLY SendMessage(hTrack,TBM_SETRANGEMAX,TRUE,MAX_POLL) ;// MAXDLY SendMessage (hTrack, TBM_SETTICFREQ, 10, TRUE) ; // 10 ticks (MAXDLY - MINDLY)
: : SendMessage ( hTrack , TBM_SETPOS , TRUE , MAX_POLL + MINJPOLL - g_pol l_pps ) ; // 1
// Fonts int i = 0; while (ALL_TEXT_θ[i] )
GetDlgltem (ALLJTEXTJD [i++] ) - >SetFont (Scg_text_font ) ;
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
void COdlg: :OnUpdateAutoEb()
{ int tpm = GetDlgl temlnt ( IDC JAUTO_EB , NULL , TRUE ) ; if ( (g_place_tpm ! = tpm) ScSe ( tpm >= MINJAUTO) Sc& ( tpm < = MAX_AUTO ) ) { g_place_delay = 60000 /tpm ; g_place_tpm = tpm;
HWND hTrack = GetDlgltem ( IDCJAUTOJ3LD) - >m_hWnd;
:: SendMessage (hTrack, TBM_SETPOS, TRUE, MAXJAUTO + MINJAUTO - tpm);
} } void COdlg: :OnUpdatePollEb()
{ int poll = GetDlgltemlnt (IDC_POLL_EB, NULL, TRUE) ; if ( (g_place_tpm != poll) ScSc (poll >= MIN_AUTO) ScSc (poll <= MAXJAUTO) ) g_poll_delay = 1000/poll; g_poll_pps = poll;
HWND hTrack = GetDlgltem (IDC_POLLJ≤LD) - >m_hWnd;
:: SendMessage (hTrack, TBM_SETPOS, TRUE, MAX POLL + MIN POLL - poll); }
} void COdlg: :OnUpdateDlyEb()
{ int dly = GetDlgltemlnt ( IDC_DLY_EB , NULL , TRUE ) ,- if ( (g_f ill_delay ! = dly) ScSc (dly >= MINJDLY) ScSc (dly < = MAXJDLY) ) { g_fill_delay = dly;
HWND hTrack = GetDlgltem ( IDC_DLY_SLD) - m_hWnd;
:: SendMessage (hTrack, TBM_SETPOS, TRUE, MAX DLY + MIN DLY - dly); }
}
void COdlg: :OnColor()
{
CHOOSECOLOR cc; // common dialog box structure
COLORREF acrCustClr [16] ;
// Setup the custom colors as a grey scale for (int v=0,i=0; i < 16; v=17 * i++) acrCustClr [i] = RGB(v,v,v); 0 P 0 ^ ^ ^
// Initialize the necessary members. cc.lStructSize = sizeof (CHOOSECOLOR) ; cc.hwndOwner = NULL; // = hwnd; cc.lpCustColors = (LPDWORD) acrCustClr; cc. Flags = CCJFULLOPEN; // CC_PREVENTFULLOPEN
if (ChooseColor (Sccc) ) { g_new_color = cc . rgbResult ,- // lpCustColors } else {
GetParentFrame ->SetMessageText ( "Color was not changed";
void COdlg: :OnClrstats 0
{ g_clear_stats++ ;
} void COdlg: :OnOracreate 0
{
// Create the database in oracle int org ora_state = g_ora_state;
if (g_ora_state == 0) if (oraconn (g_oracle_con_str) )
MessageBox ( "Oracle Connect Failed"); else g_ora_state = 1; if (g_ora_state) { if (oracreate 0 )
MessageBox ( "Oracle oracreate Failed"); if (org_ora_state == 0) if (oradisc () )
MessageBox ("Oracle Disconnect Failed"); else g_ora_state = 0;
// Odlg.h : header file //
///////////////////////////////////////////////////////////////////////////// // COdlg dialog class COdlg : public CDialog
{
// Construction public:
COdlg (CWnd* pParent = NULL); // standard constructor
// Dialog Data
// ( {AFX_DATA (COdlg) enum { IDD = IDDJDJDLG } ;
// NOTE: the ClassWizard will add data members here //} }AFXJDATA CString m_inst; // COentryView* m_parentptr,-
// Overrides
// ClassWizard generated virtual function overrides
//{{AFXJVIRTUAL (COdlg) protected : virtual void DoDataExchange (CDataExchange* pDX) ,- // DDX/DDV support
//} }AFX_VIRTUAL
// Implementation protected:
// Generated message map functions IpCreateStruct); UINT nPos , CScrollBar* pScrollBar);
Figure imgf000539_0001
User: root Host : bunny Class: bunny Job: stdm
// oentrdoc . cpp : implementation of the COentryDoc class // ttinclude " stdafx . h" ttinclude "oentry . h" //ttinclude "OpDlg . h" ttinclude "oentrdoc . h" ttifdef JDEBUG ttundef THISJFILE static char BASED_CODE THISJFILE [] = FILE ; ttendif II II II
II COentryDoc
IMPLEMENTJDYNCREATE (COentryDoc, CDocument)
BΞGINJMESSAGΞJMAP (COentryDoc , CDocument) //{ (AFXJMSGJMAP (COentryDoc)
// NOTE - the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see in these blocks of generated code //} }AFXJMSGJMAP ENDJMESSAGEJMAP ( ) mmmiimmmmimmimmmmmmimmiii/iiiii II
II COentryDoc construction/destruction
COentryDoc : : COentryDoc ( )
{
// TODO: add one-time construction code here
COentryDoc : : ~COentryDoc ( ) {
BOOL COentryDoc : :OnNewDocument ( ) if ( ! CDocument : :OnNewDocument ( ) ) return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document) return TRUE;
}
///////////////////////////////////////////////////////////////////////////// // COentryDoc serialization void COentryDoc :: Serialize (CArchiveSe ar)
{ if (ar . IsStoring )
// TODO: add storing code here } else 000539
(
// TODO: add loading code here
///////////////////////////////////////////////////////////////////////////// // COentryDoc diagnostics ttifdef JDEBUG void COentryDoc ::AssertValid ( ) const
{
CDocument: :AssertValid 0 ,-
} void COentryDoc :: Dump (CDumpContextSc dc) const
{
CDocument : : Dump (dc ) ;
} ttendif / /JDEBUG I II II COentryDoc commands
// oentrdoc.h : interface of the COentryDoc class // class COentryDoc : public CDocument
{ protected: // create from serialization only
COentryDoc () ,-
DECLAREJDYNCREATE (COentryDoc)
// Attributes public :
// Operations public :
// Overrides
// ClassWizard generated virtual function overrides
//{ (AFXJVIRTUAL (COentryDoc) • ■ public : virtual BOOL OnNewDocument () ;
//} }AFXJVIRTUAL
// Implementation public : virtual "COentryDoc () ; virtual void Serialize (CArchiveSc ar) ; // overridden for document i/o ttifdef JDEBUG virtual void AssertValid ( ) const; virtual void Dump (CDumpContextSc dc) const; ttendif protected:
// Generated message map functions protected:
// { {AFXJMSG (COentryDoc)
// NOTE - the ClassWizard will add and remove member functions h // DO NOT EDIT what you see in these blocks of generated code //}}AFXJMSG DECLARE MESSAGE MAP ( )
}; "
/////////////////////////////////////////////////////////////////////////////
// oentrvw . h : interface of the COentryView class //
I llll ttdef ine MESSAGEREADY WMJJSER + 3000 //ttdef ine IDDJTPSTIMER 100 class COentryView : publ ic CFormView
{ protected: // create from serialization only
COentryVie () ;
DECLAREJDYNCREATE (COentryView) public:
//{ (AFXJDATA (COentryView) enum { IDD = IDDJENTRYJFORM } ; int mJDrderMode;
CString m_inst ;
BOOL m_sendreply;
//} } FXJDATA BOOL m_runflag; // Running or not int m_millisec; // Delay when ordering int m_mes_sent ,- int m_mes_rec; int m_rec_sent ,- int m rec rec;
HBRUSH mjbrush; COLORREF m_color; COLORREF mJoox_color; CString m_que ,- CRect m color box rec;
int m_order; int m_order_num; int m_tran_state; int m_tran_rec; int m_tran_sent; int m_auto_tran,- int m_auto_rand; int m_auto_commit ; void AutoRunO ,- void color_the_box (COLORREF c, BOOL update); void CmdLine (int pass) ; void OnCommit (int action); void OnAnyUserActionO; void OnColor () ,- void ShowRateBar (int act) ; void PlaceOrFillMode (int mode int DbOrder (char *cust, char *item, int qty) ; int OraOrder (char *cust, char *item int qty) void LoadQList (int mode) ; void ClearDisplay ()
CDbDlg dbd; COdlg o_dlg ,-
// Attributes 000542
public :
COentryDoc* GetDocument ( )
// Operations public:
// Overrides
// ClassWizard generated virtual function overrides
//{ (AFXJ/TRTUAL (COentryView) public : virtual void OnlnitialUpdate 0 ; protected : virtual void DoDataExchange (CDataExchange* pDX) ; // DDX/DDV support virtual BOOL OnPreparePrinting (CPrintlnfo* plnfo); virtual void OnBeginPrinting (CDC* pDC, CPrintlnfo* plnfo); virtual void OnEndPrinting (CDC* pDC, CPrintlnfo* plnfo); virtual void OnPrint(CDC* pDC, CPrintlnfo*),- virtual void OnDraw(CDC* pDC) ,-
//}}AFXJVIRTUAL
// Implementation public: virtual "COentryView () ; ttifdef JDEBUG virtual void AssertValid ( ) const; virtual void Dump (CDumpContextSc dc) const; ttendif protected :
Figure imgf000545_0001
ttifndef JDEBUG // debug version in oentrvw. cpp inline COentryDoc* COentryView: :GetDocumen ()
( return (COentryDoc* ) m_pDocument ; } ttendif iiiiiiiiiimmmmiimmiiimmiiiimimmmmimmiiiiimiii
// oentry . cpp : Defines the class behaviors for the application . // ttinclude " stdafx . h" ttinclude "oentry . h" ttinclude "mainfrm . h" ttinclude "oentrdoc . h" ttinclude "dbdlg . h" ttinclude "Odlg . h" ttinclude "oentrvw . h" ttifdef JDEBUG ttundef THIS_FILE static char BASED_CODE THIS_FILE [] = FILE ; ttendif
///////////////////////////////////////////////////////////////////////////// // COentryApp
BEGINJMESSAGEJMAP (COentryApp, CWinApp)
// { (AFXJMSGJMAP (COentryApp)
ON_COMMAND (ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros her // DO NOT EDIT what you see in these blocks of generated code
//} }AFX_MSG_MAP
// Standard file based document commands
ONJCOMMAND ( ID_FILE_NEW, CWinApp : : OnFileNew)
ON_COMMAND(ID_FILEJDPEN, CWinApp: :OnFileOpen)
// Standard print setup command
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp: :OnFilePrintSetup) ENDJMESSAGEJMAP ( )
///////////////////////////////////////////////////////////////////////////// // COentryApp construction
COentryApp : : COentryApp ()
// TODO: add construction code here,
// Place all significant initialization in Initlnstance } i IiI mThei monemanidmonmlymCOemntmryApipmobmjecmt 1111111111/1/ 11 inn iiim 111
COentryApp theApp;
///////////////////////////////////////////////////////////////////////////// // COentryApp initialization
BOOL COentryApp: : Initlnstance ()
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
Enable3dControls ;
LoadStdProfileSettings () ; // Load standard INI file options (including
// Register the application's document templates. Document templates // serve as the connection between documents, frame windows and views.
CSmgleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTe plate (
IDRJMAINFRAME,
RUNTIMEJCLASS (COentryDoc) ,
RUNTIME_CLASS (CMainFrame) , // main SDI frame window
RUNTIME_CLASS (COentryView) ) ; AddDocTe plate (pDocTemplate) ,-
// create a new (empty) document
OnFileNew ( ) ,- if (m lpCmdLinetO] != '\0')
{
// TODO: add command line processing here
return TRUE;
}
///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog
{ public :
CAboutDlg ( ) ;
// Dialog Data
// { {AFXJDATA (CAboutDlg) enum { IDD = IDD_ABOUTBOX } ; //} }AFXJDATA
CFont m_title_font;
// Implementation protected : virtual void DoDataExchange ( CDataExchange* pDX) ; // DDX/DDV support
// { { AFX_MSG (CAboutDlg) virtual BOOL OnlnitDialog ( ) ;
// } } AFXJMSG
DECLARE MESSAGE MAP ( )
} ; ~
CAboutDlg : : CAboutDlg ( ) : CDialog ( CAboutDlg : : IDD)
// { { AFX_DATA_INIT (CAboutDlg) // } }AFX_DATA_INIT
void CAboutDlg : : DoDataExchange ( CDataExchange* pDX)
{
CDialog : : DoDataExchange (pDX) ;
// { (AFXJDATAJMAP (CAboutDlg) //} }AFX_DATA_MAP
BEGINJMESSAGEJMAP (CAboutDlg, CDialog)
//{ (AFXJMSGJMAP (CAboutDlg)
//}}AFXJMSG_MAP ENDJMESSAGEJMAP ( )
// App command to run the dialog void COentryApp : : OnAppAbout ( )
CAboutDlg aboutDlg; aboutDlg . DoModal ( ) ;
///////////////////////////////////////////////////////////////////////////// // COentryApp commands
BOOL CAboutDlg: :OnlnitDialog ()
CDialog: : OnlnitDialog ( ) ;
LOGFONT If; memset (Self, 0, sizeof (LOGFONT) ) ; strcpy (If .IfFaceName, "Monotype Corsiva") ,- lf.lfHeight = 24; m_title_font . CreateFontlndirect (Slf) ;
GetDlgltem ( IDC_ABOUTl) ->SetFont(Scm title font)
return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE
// oentry. h : main header file for the OENTRY application
// ttdefine MINJDLY 0 ttdefine MAXJDLY 5000 ttdefine MIN_AUTO 2 ttdefine MAX_AUTO 3000 ttdefine MIN_POLL 1 ttdefine MAX_POLL 100 ttifndef AFXWINJH tterror include 'stdafx.h' before including this file for PCH ttendif ttinclude "resource. h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// COentryApp:
// See oentry. cpp for the implementation of this class
// class COentryApp : public CWinApp
{ public :
COentryApp () ;
// Overrides
// ClassWizard generated virtual function overrides
// ( {AFX_VIRTUAL (COentryApp) public : virtual BOOL Initlnstance O ;
//}}AFXJVIRTUAL
// Implementation
//{ {AFXJMSG (COentryApp) afx_msg void OnAppAbout ( ) ;
// NOTE - the ClassWizard will add and remove member functions h // DO NOT EDIT what you see in these blocks of generated code
//}}AFX_MSG
DECLARE MESSAGE MAP ( )
}; ~
/////////////////////////////////////////////////////////////////////////////
// OPDLG . cpp : implementation file // ttinclude " stdafx . h" ttinclude "oentry . h" ttinclude "OPDLG . h" ttifdef JDEBUG ttdefine new DEBUGJNEW ttundef THIS_FILE static char THIS_FILE [] = FILE ; ttendif extern int g_options_run;
l I 1llOlPlD lLlGlldl Ill/Ill lllll I //I//I/I II II 11/111 /////III III III
OPDLG: : OPDLG (CWnd* pParent /*=NULL*/)
: CDialog (OPDLG : :IDD_0_DLG, pParent)
//{ (AFX_DATA_INIT (OPDLG)
// NOTE: the ClassWizard will add member initialization here //} }AFX_DATA_INIT
void OPDLG: : DoDataExchange (CDataExchange* pDX)
CDialog: :DoDataExchange (pDX) ,- // { {AFXJDATAJMAP (OPDLG)
// NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX DATA MAP
BEGINJMESSAGEJMAP (OPDLG, CDialog)
//{ (AFXJMSGJMAP (OPDLG)
//}}AFXJMSGJMAP END_MESSAGEJMAP ( ) i
II OPDLG message handlers void OPDLG: :OnOK
{ g_options_run = 40 ; // Re-enable the options call button this- >DestroyWindow ( ) ,-
CDialog : : OnOK ; }
// OPDLG . h : header file //
///////////////////////////////////////////////////////////////////////////// // OPDLG dialog class OPDLG : public CDialog
{
// Construction public :
OPDLG (CWnd* pParent = NULL); // standard constructor
// Dialog Data
// { (AFXJDATA (OPDLG) // enum { IDD = IDDJDPJDLG } ;
// NOTE: the ClassWizard will add data members here
//}}AFXJDATA
// Overrides
// ClassWizard generated virtual function overrides
// { (AFXJVIRTUAL (OPDLG) protected : virtual void DoDataExchange (CDataExchange* pDX) ,- // DDX/DDV support
//}}AFXJVIRTUAL
// Implementation protected:
// Generated message map functions
// { (AFX_MSG (OPDLG) virtual void OnOKO;
//}}AFXJMSG
DECLARE MESSAGE MAP ( )
}; ~
// OptDlg . cpp : implementation file // ttinclude " stdafx . h" ttinclude "oentry . h" ttinclude "OptDlg . h"
ttifdef JDEBUG ttdefine new DEBUG_NEW ttundef THIS_FILE static char THIS_FILE [] = FILE ; ttendif
extern int g_options_run ;
I IIIIOIpIItDI IlgIIdIiIaIIloI igmmimimmi n iiiiiin i/imiin/m nm im m i
OptDlg: :OptDlg (CWnd* pParent /*=NULL*/) : CDialog (OptDlg :: IDD, pParent)
//{ (AFX_DATA_INIT (OptDlg)
// NOTE: the ClassWizard will add member initialization here //} }AFXJDATA_INIT
void OptDlg: :DoDataExchange (CDataExchange* pDX)
CDialog: :DoDataExchange (pDX) ; // { {AFX_DATA_MAP (OptDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here // } }AFX_DATA_MAP
Figure imgf000553_0001
n IInOp it iDnlg inmessage hand nlemrs nn imiimmiii imiimmi void OptDlg: :OnDone () g_options_run = 40; // Re-enable the options call button this->DestroyWindow() ;
void OptDlg: :OnDestroy()
{ g_options_run = 40; // Re-enable the options call button
CDialog: :OnDestroy() ,-
} int OptDlg: : OnCreate (LPCREATESTRUCT IpCreateStruct) if (CDialog: :OnCreate (IpCreateStruct) == -l) return -1; g_options_run = 1; // Start return 0;
// OptDlg. h : header file //
///////////////////////////////////////////////////////////////////////////// // OptDlg dialog class OptDlg : public CDialog
{
// Construction public :
OptDlg (CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{ (AFXJDATA (OptDlg) // enum { IDD = IDDJDPTIONSJDLG } ;
//} }AFXJDATA
// Overrides
// ClassWizard generated virtual function overrides
//{ {AFXJVIRTUAL (OptDlg) protected: virtual void DoDataExchange (CDataExchange* pDX) ; // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation protected:
// Generated message map functions
IpCreateStruct);
Figure imgf000555_0001
//{ {NOJDEPENDENCIES} }
// Microsoft Developer Studio generated include file.
// Used by oentry. re
// ttdefine IDD_ABOUTBOX 100 ttdefine IDD_OENTRY_FORM 101 ttdefine IDRJMAINFRAME 128 ttdefine IDRJDENTRYTYPE 129 ttdefine IDI_ICON_Q 130 ttdefine IDB_BITMAPTEST 131 ttdefine IDD_DBDLG 133 ttdefine IDDJDJDLG 138 ttdefine IDR_3DIMES 145 ttdefine IDR_3DMDS 146 ttdefine IDI_ICON_TRASH 147 ttdefine IDI_IC0N_TRASH1 148 ttdefine IDI_WAIT0 149 ttdefine IDIJWAIT1 150 ttdefine IDI_WAIT2 151 ttdefine IDI_WAIT3 152 ttdefine IDI_FILL0 153 ttdefine IDI_FILL1 154 ttdefine IDI_FILL2 155 ttdefine IDI_WAIT4 156 ttdefine IDIJWAIT5 157 ttdefine IDI_WAIT6 158 ttdefine IDCJAUTOB 1000 ttdefine IDC_EXITB 1001 ttdefine IDCJDRDERB 1002 ttdefine IDC_CUST 1003 ttdefine IDC_ITEM 1004 ttdefine IDC_QTY 1005 ttdefine IDC_PICT 1006 ttdefine IDC_COLORB 1006 ttdefine IDCJ3ENERIC1 1007 ttdefine IDC_TPS_EB 1008 ttdefine IDCJTRANB 1010 ttdefine IDC_COL0RBOX 1011 ttdefine IDC_LOGO_Q 1012 ttdefine IDC_ABORTB 1013 ttdefine IDC_COMMITB 1014 ttdefine IDCJTOTALR 1015 ttdefine IDC_MSGS 1015 ttdefine IDC_SHOWDB 1016 ttdefine IDCJTPS 1017 ttdefine IDC_QUE 1018 ttdefine IDCJDLYMIN 1019 ttdefine IDC_DLYMAX 1020 ttdefine IDC_PLACER 1021 ttdefine IDC_AUTOMAX 1021 ttdefine IDC_PLACENOQR 1022 ttdefine IDC_AUTOMIN 1022 ttdefine IDC_QUELAB 1023 ttdefine IDC_POLLMAX 1023 ttdefine IDCJCUSTLAB 1024 ttdefine IDC_POLLMIN 1024 ttdefine IDC_ITEMLAB 1025 ttdefine IDC_QTYLAB 1026 ttdefine IDC_SENDREPC 1028 ttdefine IDC RECIPT 1029 ttdefine IDC FILLDB 1030 ttdefine IDC RECIPTS 1031 ttdefine IDC MSGS LAB 1032 ttdefine IDC RECIPTS LAB 1033 ttdefine IDC FILLR3 1034 ttdefine IDC DB 10 1038 ttdefine IDC DB QO 1039 ttdefine IDC DB SALEST 1040 ttdefine IDC DB SALES 1041 ttdefine IDC DB BOX 1042 ttdefine IDC DB REFILL 1043 ttdefine IDC ORDERS ITEMS 1044 ttdefine IDC Til 1045 ttdefine IDC T12 1046 ttdefine IDC T13 1047 ttdefine IDC T21 1048 ttdefine IDC T22 1049 ttdefine IDC DB PO 1050 ttdefine IDC T23 1051 ttdefine IDC ORDERBOX 1052 ttdefine IDC FILLTXT 1054 ttdefine IDC AUTOBOX 1055 ttdefine IDC dmd 1057 ttdefine IDC POLL BOX 1057 ttdefine IDC TRANBOX 1058 ttdefine IDC WAITO 1060 ttdefine IDC WAIT1 1061 ttdefine IDC OPTIONSB 1063 ttdefine IDC FILLO 1064 ttdefine IDC FILL1 1065 ttdefine IDC DB 11 1066 ttdefine IDC FILL2 1066 ttdefine IDC DB Ql 1067 ttdefine IDC DB PI 1068 ttdefine IDC DLY EB 1068 ttdefine IDC DB 12 1069 ttdefine IDC DLY SLD 1069 ttdefine IDC DB Q2 1070 ttdefine IDC DLY LAB 1070 ttdefine IDC DB P2 1071 ttdefine IDC AUTO EB 1071 ttdefine IDC DB 13 1072 ttdefine IDC AUTO SLD 1072 ttdefine IDC DB Q3 1073 ttdefine IDC AUTO LAB 1073 ttdefine IDC DB P3 1074 ttdefine IDC FILLBOX 1074 ttdefine IDC DB 14 1075 ttdefine IDC COLOR 1075 ttdefine IDC DB Q4 1076 ttdefine IDC POLL EB 1076 ttdefine IDC DB P4 1077 ttdefine IDC POLL SLD 1077 ttdefine IDC DB 15 1078 ttdefine IDC POLL LAB 1078 ttdefine IDC DB Q5 1079 ttdefine IDC DB P5 1080 ttdefine IDC CLRSTATS 1080 ttdefine IDC ABOUT1 1081 ttdefine IDC ORACREATE 1081 ttdefine IDC_BIG_TITLE 1082 ttdefine IDCJMODEBOX 1083 ttdefine IDCJSTATBOX 1084 ttdefine IDC_FILLR 2000 ttdefine IDCJTOTALS 2001
// Next default values for new objects
// ttifdef APSTUDIO_INVOKED ttifndef APSTUDIO_READONLY_SYMBOLS ttdefine _APS_3D_CONTROLS 1 ttdefine _APS_NEXT_RESOURCE_VALUE 140 ttdefine _APS_NEXTjCOMMAND_VALUE 32771 ttdefine _APS_NEXT_CONTROL_VALUE 1085 ttdefine _APS_NEXT_SYMED_VALUE 101 ttendif ttendif
Having above indicated several embodiments of the Subject Invention, it will occur to those skilled in the art that modifications and alternatives can be practiced within the spirit of the invention, it is accordingly intended to define the scope of the invention only as indicated in the following claims.

Claims

WHAT IS CLAIMED IS:
1. A message queuing system, comprising: means for transmitting a transactional message having an associated message queue including the state of the queue, message queue data and log records; and, means at a recipient site for storing said transactional message on a single disk in a single file utilizing a combined on- disk file structure for said message queue data and said log records .
2. The system of Claim 1, and further including a read/write head for accessing said single disk and means for driving said head in a single forward direction during a write operation.
3. The system of Claim 1, and further including a queue entry management table placed on said disk at preselected locations, said table having a control information block, at least one message block and at least one log record.
4. The system of Claim 3, wherein said preselected locations correspond to a fixed offset from the beginning of said file, thus to permit rapid identification of the most recent state of the message queue data.
5. The system of Claim 4 and further including means at said recipient site for recovering said message queue upon interruption of said transmission responsive to the most recent queue entry management table prior to said information, whereby the last valid information received and stored is located from information contained in said most recent queue entry management table .
6. The system of Claim 5, wherein said file is divided into sectors, and wherein said offset places a queue entry management table at the beginning of a sector such that said table constitutes a checkpoint for the location of a sector having valid information, whereby the last valid information prior to said interruption may be rapidly located through the identification of the sector containing said most recent table.
7. The system of Claim 2 , wherein said management queue table is written in contiguous blocks, the result of a single file, forward write direction and contiguous message queue data block system being minimization of seek time, increase in throughout and rapid recovery from a transmission interruption.
PCT/US1997/020561 1996-11-14 1997-11-11 Log based data architecture for a transactional message queuing system WO1998021654A1 (en)

Priority Applications (3)

Application Number Priority Date Filing Date Title
AU51771/98A AU5177198A (en) 1996-11-14 1997-11-11 Log based data architecture for a transactional message queuing system
EP97946642A EP1015973A4 (en) 1996-11-14 1997-11-11 Log based data architecture for a transactional message queuing system
JP52274998A JP4280306B2 (en) 1996-11-14 1997-11-11 Log-based data architecture for transaction message queuing systems

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
US3090596P 1996-11-14 1996-11-14
US60/030,905 1996-11-14

Publications (1)

Publication Number Publication Date
WO1998021654A1 true WO1998021654A1 (en) 1998-05-22

Family

ID=21856622

Family Applications (1)

Application Number Title Priority Date Filing Date
PCT/US1997/020561 WO1998021654A1 (en) 1996-11-14 1997-11-11 Log based data architecture for a transactional message queuing system

Country Status (4)

Country Link
EP (1) EP1015973A4 (en)
JP (1) JP4280306B2 (en)
AU (1) AU5177198A (en)
WO (1) WO1998021654A1 (en)

Cited By (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO2005098676A2 (en) 2004-03-31 2005-10-20 Gemini Mobile Technologies, Inc. Synchronous message queues
US7107293B2 (en) 2003-04-30 2006-09-12 International Business Machines Corporation Nested recovery scope management for stateless recovery agents
US10230670B1 (en) 2014-11-10 2019-03-12 Google Llc Watermark-based message queue
CN111984198A (en) * 2020-08-25 2020-11-24 北京一起教育信息咨询有限责任公司 Message queue implementation method and device and electronic equipment
CN115185616A (en) * 2022-09-14 2022-10-14 深圳依时货拉拉科技有限公司 Business rule engine and processing method thereof

Citations (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5465328A (en) * 1993-03-30 1995-11-07 International Business Machines Corporation Fault-tolerant transaction-oriented data processing
US5555388A (en) * 1992-08-20 1996-09-10 Borland International, Inc. Multi-user system and methods providing improved file management by reading

Family Cites Families (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
GB2263988B (en) * 1992-02-04 1996-05-22 Digital Equipment Corp Work flow management system and method
GB2276739A (en) * 1993-03-30 1994-10-05 Ibm System for storing persistent and non-persistent queued data.

Patent Citations (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5555388A (en) * 1992-08-20 1996-09-10 Borland International, Inc. Multi-user system and methods providing improved file management by reading
US5465328A (en) * 1993-03-30 1995-11-07 International Business Machines Corporation Fault-tolerant transaction-oriented data processing

Non-Patent Citations (1)

* Cited by examiner, † Cited by third party
Title
See also references of EP1015973A4 *

Cited By (12)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US7107293B2 (en) 2003-04-30 2006-09-12 International Business Machines Corporation Nested recovery scope management for stateless recovery agents
US8572044B2 (en) 2003-04-30 2013-10-29 International Business Machines Corporation Nested recovery scope management for stateless recovery agents
WO2005098676A2 (en) 2004-03-31 2005-10-20 Gemini Mobile Technologies, Inc. Synchronous message queues
EP1738288A2 (en) * 2004-03-31 2007-01-03 Gemini Mobile Technologies, Inc. Synchronous message queues
EP1738288A4 (en) * 2004-03-31 2009-05-06 Gemini Mobile Technologies Inc Synchronous message queues
US10230670B1 (en) 2014-11-10 2019-03-12 Google Llc Watermark-based message queue
US10951572B1 (en) 2014-11-10 2021-03-16 Google Llc Watermark-based message queue
US11736433B2 (en) 2014-11-10 2023-08-22 Google Llc Watermark-based message queue
CN111984198A (en) * 2020-08-25 2020-11-24 北京一起教育信息咨询有限责任公司 Message queue implementation method and device and electronic equipment
CN111984198B (en) * 2020-08-25 2024-02-27 北京一起教育信息咨询有限责任公司 Message queue implementation method and device and electronic equipment
CN115185616A (en) * 2022-09-14 2022-10-14 深圳依时货拉拉科技有限公司 Business rule engine and processing method thereof
CN115185616B (en) * 2022-09-14 2022-12-13 深圳依时货拉拉科技有限公司 Business rule engine device and processing method of business rule engine

Also Published As

Publication number Publication date
JP2001502455A (en) 2001-02-20
EP1015973A1 (en) 2000-07-05
JP4280306B2 (en) 2009-06-17
AU5177198A (en) 1998-06-03
EP1015973A4 (en) 2002-09-25

Similar Documents

Publication Publication Date Title
US6353834B1 (en) Log based data architecture for a transactional message queuing system
US6873995B2 (en) Method, system, and program product for transaction management in a distributed content management application
US6581110B1 (en) Method and system for reading and propagating authenticated time throughout a worldwide enterprise system
CA2222347C (en) System and method for efficiently transferring datastreams in a multimedia system
CN1794207B (en) Method and system for implenmenting cache consistency
US7721003B2 (en) System and method to synchronize OSGi bundle inventories between an OSGi bundle server and a client
US6938057B2 (en) Method and apparatus for networked backup storage
US7523219B2 (en) Method and apparatus for affinity of users to application servers
AU2005200561B8 (en) Credential roaming
US9634951B1 (en) Autonomous agent messaging
CN113396407A (en) System and method for augmenting database applications using blockchain techniques
EP0602822A2 (en) Remote data duplexing
CN109684414B (en) Method, device and equipment for synchronizing block data and storage medium
US7478099B1 (en) Methods and apparatus for collecting database transactions
CN108337303A (en) A kind of method of data synchronization and distributed system
US10924587B1 (en) Live migration for highly available data stores
CN110399227B (en) Data access method, device and storage medium
US20070055968A1 (en) Reliable BIOS updates
CN111124993A (en) Method, apparatus and program product for reducing cache data mirroring latency during I/O processing
CN112822091B (en) Message processing method and device
WO1998021654A1 (en) Log based data architecture for a transactional message queuing system
US10318385B2 (en) Service recovery using snapshots and interservice messages
US6748508B1 (en) Method and apparatus for buffering in multi-node, data distribution architectures
US7228455B2 (en) Transaction branch management to ensure maximum branch completion in the face of failure
JP2002530750A (en) Protocol for synchronizing parallel processors in mobile communication systems

Legal Events

Date Code Title Description
AK Designated states

Kind code of ref document: A1

Designated state(s): AU CA CN IL JP KR MX NO NZ SG

AL Designated countries for regional patents

Kind code of ref document: A1

Designated state(s): AT BE CH DE DK ES FI FR GB GR IE IT LU MC NL PT SE

121 Ep: the epo has been informed by wipo that ep was designated in this application
ENP Entry into the national phase

Ref country code: JP

Ref document number: 1998 522749

Kind code of ref document: A

Format of ref document f/p: F

WWE Wipo information: entry into national phase

Ref document number: 1997946642

Country of ref document: EP

WWP Wipo information: published in national office

Ref document number: 1997946642

Country of ref document: EP

WWW Wipo information: withdrawn in national office

Ref document number: 1997946642

Country of ref document: EP